에듀테크 프로젝트 대시보드
위상 정렬 (Topological Sort)
"A를 하기 전에 B를 먼저 끝내야 한다" 같은 선후 관계가 있는 일들을, 규칙을 하나도 어기지 않는 순서로 한 줄로 세우는 것이 위상 정렬이다. 선수과목 이수 순서, 빌드 시스템의 컴파일 순서, 엑셀 수식 재계산 순서가 모두 같은 문제다. 관계를 방향 그래프(DAG) 로 그리면, 화살표를 거스르지 않는 일렬 나열을 찾는 일이 된다. 단, 그래프에 사이클이 있으면 (서로가 서로의 선행 조건) 그런 순서는 존재하지 않는다.
from collections import deque def topological_sort(n, edges): adj = [[] for _ in range(n)] indeg = [0] * n for u, v in edges: # u를 끝내야 v를 할 수 있다 adj[u].append(v) indeg[v] += 1 q = deque(i for i in range(n) if indeg[i] == 0) order = [] while q: u = q.popleft() # 선행 조건이 모두 끝난 일 order.append(u) for v in adj[u]: indeg[v] -= 1 # 선행 하나 해결 if indeg[v] == 0: q.append(v) if len(order) != n: raise ValueError("사이클이 있어 위상 정렬 불가") return order
len(order) < n 이면 → 남은 노드들이 서로 순환 의존. 위상 정렬이 존재하지 않는다 (사이클 감지).O(V + E) — 노드와 간선을 각각 한 번씩만 본다.C1 = A1 + B1 처럼 셀 참조 그래프를 위상 정렬해 재계산 순서 결정. 순환 참조 경고가 바로 이 사이클 감지.| 방식 | 자료구조 | 사이클 감지 | 비고 |
|---|---|---|---|
| Kahn (BFS) | 큐 + 진입차수 | order 길이 < n | 직관적, 병렬화 쉬움 |
| DFS post-order | 재귀 스택 | back edge(회색 노드) | 코드 짧음 |