깊이 우선 검색

Depth-first search
깊이 우선 검색
Order in which the nodes get expanded
노드를 방문하는 순서
학급검색 알고리즘
data 구조그래프
최악의 경우 성능 ( +) \O ( + E \ display style ( V + E ) \ display O ( bd ) \ display O ( { } \ display style O ( b { d } ) 。
최악의 경우 공간의 복잡성 { O 전체 그래프를 반복하지 않고 이동하는 경우 O(가장 긴 경로 길이 검색) = O d { O d 중복 노드를 제거하지 않고 암시 그래프를 표시합니다.

깊이 우선 검색(DFS)은 트리 또는 그래프 데이터 구조를 통과하거나 검색하는 알고리즘입니다.알고리즘은 루트노드에서 시작하여(그래프의 경우 임의의 노드를 루트노드로 선택) 각 브랜치를 따라 가능한 한 멀리 탐색한 후 역추적합니다.지정된 분기를 따라 지금까지 발견된 노드를 추적하려면 추가 메모리(일반적으로 스택)가 필요합니다.그래프의 역추적에는 도움이 됩니다.

깊이 우선 탐색의 버전은 19세기에 프랑스 수학자 샤를 피에르 트레모에[1] 의해 [2][3]미로를 풀기 위한 전략으로 연구되었다.

특성.

DFS의 시간과 공간 분석은 응용 영역에 따라 다릅니다.이론 컴퓨터 과학에서 DFS는 일반적으로 그래프 전체를 이동하는 데 사용되며, + E { O+ { V 정점 수, { E 소요됩니다[4]그래프 크기가 선형입니다.이러한 응용 프로그램에서는 최악의 경우 O)(\( V를 사용하여 현재 검색 경로에 정점 스택과 이미 방문한 정점 집합을 저장합니다.따라서 이 설정에서는 시간 및 공간 경계가 폭 우선 검색과 동일하며 이들 2개의 알고리즘 중 어느 것을 사용할지는 복잡성에 따라 달라지며 두 알고리즘이 생성하는 정점 순서의 다른 속성에 따라 달라집니다.

인공지능이나 웹 크롤링에서의 솔루션 검색과 같은 특정 도메인과 관련된 DFS 애플리케이션의 경우, 통과하는 그래프가 너무 커서 전체를 방문하기 어렵거나 무한대(DFS가 종료되지 않을 수 있음)인 경우가 많습니다.이러한 경우 검색은 제한된 깊이까지만 수행됩니다. 메모리나 디스크 공간 등의 제한된 리소스로 인해 일반적으로 이전에 방문한 모든 정점의 집합을 추적하기 위해 데이터 구조를 사용하지 않습니다.제한된 깊이까지 검색이 수행될 때, 시간은 확장된 정점과 모서리 수 측면에서 여전히 선형입니다(일부 정점은 두 번 이상 검색되고 다른 정점은 전혀 검색되지 않기 때문에 이 숫자는 전체 그래프의 크기와 동일하지 않습니다). 그러나 DFS의 이 변형된 공간의 복잡성은 dep에 비례합니다.그 결과 폭 우선 검색을 사용하여 동일한 깊이까지 검색하는 데 필요한 공간보다 훨씬 작습니다.이러한 애플리케이션의 경우, DFS는 가능성이 높은 브랜치를 선택하는 휴리스틱 메서드에 훨씬 적합합니다.적절한 깊이 한계를 사전에 알 수 없는 경우, 반복적인 깊이 우선 탐색은 일련의 증가하는 한계와 함께 DFS를 반복적으로 적용한다.인공지능 분석모드에서 분기계수가 1보다 크면 레벨당 노드수의 기하학적 증가에 의해 정확한 깊이 한계가 알려진 경우보다 반복 심도가 일정계수만 실행시간을 증가시킨다.

DFS를 사용하여 그래프 노드의 샘플을 수집할 수도 있습니다.그러나 불완전한 DFS는 불완전한 BFS와 마찬가지로 높은 수준의 노드에 치우쳐 있습니다.

깊이 우선 검색의 애니메이션 예

다음 그래프의 경우:

An undirected graph with edges AB, BD, BF, FE, AC, CG, AE

노드 A에서 시작하는 깊이 우선 검색은 표시된 그래프의 왼쪽 가장자리가 오른쪽 가장자리보다 먼저 선택된다고 가정하고, 검색이 이전에 방문한 노드를 기억하고 반복하지 않는다고 가정하면(이것은 작은 그래프이므로), A, B, D, F, E, C, G 순으로 노드를 방문합니다.이 검색에서 횡단된 가장자리는 그래프 이론에서 중요한 응용 분야를 가진 구조인 Trémaux 트리를 형성합니다.이전에 방문한 노드를 기억하지 않고 동일한 검색을 실행하면 A, B, D, F, E, A, B, D, F, E 사이클에 걸려 C, G에 도달하지 않는 노드가 영원히 방문됩니다.

반복 심화는 이 무한 루프를 피하기 위한 하나의 기술로 모든 노드에 도달합니다.

깊이 우선 검색 출력

스패닝 트리에 의해 정의된4종류의 엣지

그래프의 깊이 우선 검색 결과는 검색 중에 도달한 정점의 스패닝 트리로 쉽게 설명할 수 있습니다.이 스패닝 트리를 기반으로 원래 그래프의 가장자리는 트리의 노드에서 하위 노드 중 하나를 가리키는 전방 에지, 노드에서 상위 노드 중 하나를 가리키는 후방 에지교차 에지 등 세 가지 클래스로 나눌 수 있습니다.경우에 따라서는 스패닝트리 자체에 속하는 트리 에지가 전방 에지와는 별도로 분류됩니다.원래 그래프가 무방향인 경우 그래프의 모든 가장자리가 트리 가장자리 또는 후면 모서리입니다.

정점 순서

깊이 우선 검색을 사용하여 그래프 또는 트리의 정점을 선형으로 정렬할 수도 있습니다.여기에는 다음 4가지 방법이 있습니다.

  • 사전 순서는 깊이 우선 검색 알고리즘이 처음 방문한 순서대로 정점 목록입니다.이는 이 문서의 앞부분에서처럼 검색 진행 상황을 간략하고 자연스럽게 설명하는 방법입니다. 트리의 사전 순서는 폴란드어 표기법에서의 식입니다.
  • 후순서는 알고리즘이 마지막으로 방문한 순서대로 정점의 목록입니다.식 트리의 후순서는 폴란드어 역표기 식입니다.
  • 역순서는 사전순서의 역순서, 즉 첫 번째 방문 순서의 정점 목록입니다.역순서는 후순서와 다릅니다.
  • 역순서는 후순서의 역순서, 즉 마지막 방문 순서의 반대 순서로 정점의 목록입니다.역순서는 예약순서와 다릅니다.

바이너리 트리의 경우 순서와 역순서가 추가로 있습니다.

예를 들어 노드 A에서 시작하는 다음 방향 그래프를 검색하는 경우 통과 순서는 A B D B A 또는 A C D C A A 중 하나입니다(A에서B 또는 C를 처음 방문하도록 선택하는 것은 알고리즘에 따라 다릅니다).노드로의 백트래킹 형식의 반복 방문은 노드에 아직 방문하지 않은 네이버가 있는지 확인하기 위해 여기에 포함됩니다(노드가 존재하지 않는 것으로 판명된 경우에도).따라서 가능한 프리오더는 A B D C 및 A C D B이며, 가능한 포스트오더는 D B C A 및 D C B A이며, 가능한 리버스 포스트오더는 A C B D 및 A B C D입니다.

A directed graph with edges AB, BD, AC, CD

역순서는 유도 비순환 그래프토폴로지 정렬을 생성합니다.이 순서는 제어 흐름의 자연스러운 선형화를 나타내는 경우가 많기 때문에 제어 흐름 분석에서도 유용합니다.위의 그래프는 다음 코드프래그먼트 내의 제어 흐름을 나타내고 있습니다.이 코드를 A B C D 또는 A C B D 순서로 고려하는 것은 자연스러운 일이지만 A B D C 또는 A C D B의 순서로 사용하는 것은 자연스러운 일이 아닙니다.

(A)이면 {B }, (A)이면 {C } D

유사 코드

입력: 출력:DFS의 [5]재귀적 구현:

절차 DFS(G, v)는 G.adjacentEdges(v)에 있는 v에서 w까지의 모든 방향 에지에 대해 검출된 라벨 v입니다.정점 w가 검출된 라벨이 없는 경우 DFS(G, w)를 재귀적으로 호출합니다.

스택에 [6]정점이 중복될 가능성이 있는 최악의 공간 O O를 가진 DFS의 비재귀적 구현:

프로시저 DFS_iterative(G, v)는 S를 스택 S.push(v)로 하고, S가 비어 있지 않은 경우 v = S.pop()으로 합니다.g.adjacentEdges(v)는 S.push(w)를 수행합니다.
An undirected graph with edges AB, BD, BF, FE, AC, CG, AE

이 두 가지 DFS 변형이 서로 반대 순서로 각 정점의 네이버를 방문합니다.재귀 변형이 방문한 v의 첫 번째 네이버가 인접 에지 목록의 첫 번째 네이버인 반면 반복 변이에서는 첫 번째 방문한 네이버가 인접 에지 목록의 마지막 네이버입니다.재귀 구현은 예제 그래프에서 A, B, D, F, E, C, G 순으로 노드를 방문합니다.비재귀 구현은 노드를 A, E, F, B, D, C, G로 방문합니다.

비재귀적 구현은 폭 우선 검색과 유사하지만 다음과 같은 두 가지 점에서 다릅니다.

  1. 큐 대신 스택을 사용합니다.
  2. 정점을 추가하기 전에 이 검사를 수행하는 대신 정점이 스택에서 팝업될 때까지 정점이 검색되었는지 여부를 확인하는 것이 지연됩니다.

G가 트리경우 폭 우선 검색 알고리즘의 큐를 스택으로 대체하면 깊이 우선 검색 알고리즘이 생성됩니다.일반 그래프의 경우 반복 깊이 우선 검색 구현의 스택을 대기열로 대체하면 너비 우선 검색 알고리즘이 생성되지만 다소 비표준적입니다.[7]

반복 깊이 우선 검색의 또 다른 가능한 구현은 노드 스택 대신 노드 네이버 목록의 반복기 스택을 사용한다.이것은 재귀 [8]DFS와 같은 트래버설을 생성합니다.

프로시저 DFS_iterative(G, v)는 S를 스택 S.push(G.adjacentEdges(v)의 반복자)로 하고, S.pek().hasNext()의 경우 w = S.pek(.next)의 경우 w가 검출된 SUSHitator의 라벨로 합니다.

적용들

미로 생성에 사용되는 깊이 우선 검색과 유사한 무작위 알고리즘입니다.

깊이 우선 검색을 구성 요소로 사용하는 알고리즘은 다음과 같습니다.

  • 연결된 구성 요소를 찾는 입니다.
  • 토폴로지 정렬.
  • 2-(가장자리 또는 정점) 연결된 구성 요소를 찾는 중입니다.
  • 3-(가장자리 또는 정점) 연결된 구성 요소를 찾는 중입니다.
  • 그래프의 브릿지 찾기.
  • 그룹제한 집합을 플롯하기 위해 단어를 생성합니다.
  • 강하게 연결된 구성 요소를 찾는 중입니다.
  • 한 종이 계통수에서 한 종에 가까운지 다른 종에 가까운지를 결정하는 것.
  • 평탄[9][10]테스트
  • 미로와 같은 하나의 해결책으로 퍼즐을 푼다.(DFS는 방문한 세트에 현재 경로의 노드만 포함시킴으로써 미로의 모든 해결책을 찾도록 적응할 수 있습니다.
  • Maze 생성에서는 랜덤화된 DFS를 사용할 수 있습니다.
  • 그래프에서 쌍커넥티비티를 찾는 중입니다.

복잡성

DFS의 계산 복잡성은 John Reif에 의해 조사되었습니다.보다 정확하게는 G { G에 O ( 1 , ...,n ) { O= ( v 1} , \ , v { } )를 표준 재귀 DFS 알고리즘에 의해 계산된 순서라고 .이 순서를 사전적 깊이 우선 검색 순서라고 합니다.John Reif는 그래프와 소스를 통해 사전적 깊이 우선 검색 순서를 계산하는 복잡성을 고려했습니다.문제의 결정 버전(일부 정점 u가 이 순서로 어떤 정점 v보다 먼저 발생하는지 테스트)은 [11]P-완전이며,[12]: 189 이는 "병렬 처리의 악몽"임을 의미합니다.

심도 우선 검색 순서(꼭 사전적 순서는 아님)는 복잡도 클래스 [13]RNC의 무작위 병렬 알고리즘에 의해 계산될 수 있다. 1997년 현재, 심도 우선 통과가 복잡도 클래스 [14]NC의 결정론적 병렬 알고리즘에 의해 구성될 수 있을지는 알려지지 않았다.

「 」를 참조해 주세요.

메모들

  1. ^ 샤를 피에르 트레모(1859년-1882년) 파리의 에콜 폴리테크니크(X:1876년), 프랑스 전신 기술자
    2010년 12월 2일 공개 콘퍼런스에서 - 아카데미 드 마콘의 Jean Pelletier-Thibert 교수 (부르군디 – 프랑스) - (연보 학술지, 2011년 3월 발행) ISSN0980-6032)
  2. ^ 를 클릭합니다Even, Shimon (2011), Graph Algorithms (2nd ed.), Cambridge University Press, pp. 46–48, ISBN 978-0-521-73653-4.
  3. ^ 를 클릭합니다Sedgewick, Robert (2002), Algorithms in C++: Graph Algorithms (3rd ed.), Pearson Education, ISBN 978-0-201-36118-6.
  4. ^ 코먼, 토마스 H, 찰스 E.리저슨, 로널드 L. 리베스트 페이지 606
  5. ^ 구드리치와 타마시아; 코르멘, 리자슨, 리베스트, 스타인
  6. ^ 93페이지, 알고리즘 설계, 클라인버그 및 타도스
  7. ^ "Stack-based graph traversal ≠ depth first search". 11011110.github.io. Retrieved 2020-06-10.
  8. ^ Sedgewick, Robert (2010). Algorithms in Java. Addison-Wesley. ISBN 978-0-201-36121-6. OCLC 837386973.
  9. ^ 를 클릭합니다Hopcroft, John; Tarjan, Robert E. (1974), "Efficient planarity testing" (PDF), Journal of the Association for Computing Machinery, 21 (4): 549–568, doi:10.1145/321850.321852, hdl:1813/6011, S2CID 6279825.
  10. ^ 를 클릭합니다de Fraysseix, H.; Ossona de Mendez, P.; Rosenstiehl, P. (2006), "Trémaux Trees and Planarity", International Journal of Foundations of Computer Science, 17 (5): 1017–1030, arXiv:math/0610935, Bibcode:2006math.....10935D, doi:10.1142/S0129054106004248, S2CID 40107560.
  11. ^ Reif, John H. (1985). "Depth-first search is inherently sequential". Information Processing Letters. 20 (5): 229–234. doi:10.1016/0020-0190(85)90024-9.
  12. ^ Mehlhorn, Kurt; Sanders, Peter (2008). Algorithms and Data Structures: The Basic Toolbox (PDF). Springer.
  13. ^ 를 클릭합니다Aggarwal, A.; Anderson, R. J. (1988), "A random NC algorithm for depth first search", Combinatorica, 8 (1): 1–12, doi:10.1007/BF02122548, MR 0951989, S2CID 29440871.
  14. ^ 를 클릭합니다Karger, David R.; Motwani, Rajeev (1997), "An NC algorithm for minimum cuts", SIAM Journal on Computing, 26 (1): 255–272, CiteSeerX 10.1.1.33.1701, doi:10.1137/S0097539794273083, MR 1431256.

레퍼런스

외부 링크