728x90
그래프와 탐색 알고리즘
- 그래프는 대상들의 관계를 나타낼 때 적합한 자료구조로 대상 나타내는 node 또는 vertex들과 그들의 연결 관계를 나타내는 Edge로 표현할 수 있다.
- 그래프는 edge가 탐색할 수 있는 방향의 존재 여부와 가중치의 여부에 따라 크게 네 가지 종류로 구분할 수 있다.
- 무향 그래프 : edge의 방향이 없는 그래프
- 유향 그래프 : edge에 방향이 있는 그래프
- 가중치 무향 그래프 : edge에 방향은 없으나 가중치가 있는 그래프
- 가중치 유향 그래프 : edge에 방향과 가중치가 있는 그래프
- 행렬의 행은 출발하는 node의 숫자, 열을 도착하는 node의 숫자로 그래프를 표현할 수 있다.
- 아래의 예는 유향 그래프를 행렬로 표현한 것을 나타낸 예시이다.
- 1번 node는 2와 3으로 연결되어 있어 행렬의 (1,2), (1,3)에 연결되었다는 의미로 1을 표시하고 그 외 연결되지 않은 node의 자리는 0으로 표시한다.
- 1번 node는 2와 3으로 연결되어 있어 행렬의 (1,2), (1,3)에 연결되었다는 의미로 1을 표시하고 그 외 연결되지 않은 node의 자리는 0으로 표시한다.
- 그래프를 탐색하며 어떤 문제의 해를 구할 때 모든 node를 방문하며 탐색해야하는 과정이 필요하다.
- 그래프의 모든 node를 빠짐없이 탐색하는 완전 탐색 알고리즘으로는 Breadth First Search(BFS)와 Depth First Search(DFS) 방법이 있다. 두 알고리즘은 한 노드를 visit하고 expand할 때 우선 순위를 두는 방식에 따라 구분된다.
Breadth-First Search(BFS)
- BFS는 방문한 노드에 인접한 노드들을 우선 방문하도록 하는 알고리즘이다.
- queue 자료구조를 사용해 visit과 expand를 모든 노드를 방문해 탐색하지 않은 노드가 없을 때 까지 반복하는 방식으로 구현한다.
- BFS 알고리즘은 다음과 같은 순서로 진행된다.
- 탐색 시작 node를 queue에 push
- queue가 empty일 때까지 반복
- queue의 가장 앞 요소를 pop
- pop 된 node를 처리하는 코드
- 해당 노드에 인접하면서 아직 방문하지 않은 node를 queue에 push & 방문 처리
- 나는 BFS로 문제를 풀 때, 전체를 구현하기 전에 전체 틀을 구성하는 코드를 먼저 작성하고 구현해야하는 내용을 주석으로 표시해놓고 풀이한다.
- 문제를 보고 python으로 BFS 알고리즘을 구현해야겠다는 판단했다면 전체 코드를 짜기 전에 아래의 코드를 먼저 작성한 후 빈 부분을 채워나간다.
from collections import deque
# queue 생성
q = deque()
# 시작 점 enqueue code 넣기
while (q): # q에 요소가 남아 있다면 반복
cur = q.pop()
for ~~ :# 인접한 node 탐색 code
# do sth
pass
- 아래는 간단한 tree 형태의 그래프를 BFS로 탐색하는 과정을 보여준다.
- a : 탐색을 시작하는 1번 노드를 queue에 push
- b : queue에 가장 앞에 있는 1번 node를 pop해 방문하고 인접한 node 2, 3을 queue에 push
- c : 2번 node를 queue에서 pop, 인점한 node 4, 5를 queue에 push
- d : 3번 node를 queue에서 pop, 인접한 node 6을 queue에 push
- e : 4번 node를 queue에서 pop, 인접한 node는 없기 때문에 push할 node는 없음
- f : 5번 node를 queue에서 pop, 인접한 node는 없기 때문에 push할 node는 없음
- g : 6번 node를 queue에서 pop, 인접한 node는 없기 때문에 push할 node는 없음
- queue가 비어있기 때문에 탐색을 종료
관련 문제
2022.08.02 - [알고리즘 공부/백준 문제풀이] - [백준 python] 14502번 연구소
2022.09.21 - [알고리즘 공부/백준 문제풀이] - [백준 python] 14499번 주사위 굴리기
2022.08.15 - [알고리즘 공부/백준 문제풀이] - [python 백준] 23288번 주사위 굴리기 2
2022.09.24 - [알고리즘 공부/백준 문제풀이] - [python 백준] 1012번 유기농 배추
DFS
- DFS는 방문한 노드에 인접한 노드 중 방문하지 않은 노드를 우선 탐색하도록 하는 알고리즘이다.
- DFS는 stack 자료구조를 사용해 구현할 수 있지만 구현의 편리함 때문에 재귀 형태로 구현하는 것이 일반적이다.
- DFS 알고리즘은 다음과 같은 순서로 진행된다.
- 가장 처음 방문할 노드를 stack에 넣는다.
- stack이 empty일 때까지 반복
- 해당 노드에 인접한 node 중 방문하지 않은 node를 방문하고 stack에 push / 방문하지 않은 node가 없다면 stack에서 pop
- stack의 가장 위에 있는 ndoe로 이동
- 나는 아래 뼈대 코드를 기억하고 문제 풀이를 한다. BFS에 비해 문제에 따라 풀이를 달리하는 경우가 많아 재귀 함수의 뼈대만 기억하고 풀이하는 편이다.
def DFS():
if (leaf node 도달 조건):
# do sth
return
for node in (인접한 node):
# 방문 표시
DFS(node)
# 방문 표시 해제
- 아래는 BFS의 예와 같은 tree 형태의 그래프를 DFS로 탐색하는 과정을 보여준다.
- a : 탐색을 시작하는 1번 노드를 stack에 push
- b : stack의 가장 위에 있는 1번에 인접한 방문하지 않은 2번 node를 방문하고 stack에 push
- c : stack의 가장 위에 있는 2번에 인접한 방문하지 않은 3번 node를 방문하고 stack에 push
- d : stack의 가장 위에 있는 3번에 인접한 방문하지 않은 node가 없으므로 stack에서 pop
- e : stack의 가장 위에 있는 2번에 인접한 방문하지 않은 4번 node를 방문하고 stack에 push
- f : stack의 가장 위에 있는 4번과 2번에 인접한 방문하지 않은 node가 없으므로 stack에서 pop
- g : stack의 가장 위에 있는 1번에 인접한 방문하지 않은 5번 node를 방문하고 stack에 push
- h : stack의 가장 위에 있는 5번에 인접한 방문하지 않은 6번 node를 방문하고 stack에 push
- i : stack의 가장 위에 있는 6번, 5번과 1번에 인접한 방문하지 않은 node가 없으므로 stack에서 pop
- stack이 비어있기 떄문에 탐색을 종료
관련 문제
2022.08.02 - [알고리즘 공부/백준 문제풀이] - [백준 python] 14502번 연구소
2022.07.31 - [알고리즘 공부/백준 문제풀이] - [백준 python] 14888번 연산자 끼워넣기
2022.08.05 - [알고리즘 공부/백준 문제풀이] - [백준 python] 14889번 스타트와 링크
조금 더 생각해보기
- 문제를 효율적으로 해결하기 위해 조건을 잘 분석해 탐색이 필요 없는 노드는 탐색하지 않도록 하는 가지치기 방법을 적용해 문제 풀이 효율을 높힐 수 있다.
'알고리즘 공부 > 개념 정리' 카테고리의 다른 글
[알고리즘] 다이나믹 프로그래밍 (0) | 2022.08.24 |
---|---|
[자료구조] Queue과 Stack (0) | 2022.08.21 |