에듀테크 프로젝트 대시보드
그래프 색칠 (Graph Coloring)
규칙은 딱 하나 — 선으로 이어진 두 점은 서로 다른 색이어야 한다. 이 단순한 퍼즐이 지도 색칠, 시험 시간표 짜기, 컴파일러의 레지스터 배정, 스도쿠, 무선 주파수 할당까지 전부 같은 문제다. 최소 몇 가지 색이면 될까? 이것을 색칠수(chromatic number) χ(G) 라고 부른다.
정점을 클릭하면 색이 바뀐다(색 없음 → 1번 색 → 2번 색 → … → 다시 색 없음). 이어진 두 정점이 같은 색이면 그 간선이 빨갛게 경고한다. 목표: 충돌 0 을 유지하면서 모든 정점을 칠하되, 되도록 적은 색으로.
※ 탐욕적 색칠(greedy): 정점을 정해진 순서로 훑으면서, 그 정점의 이웃이 아직 쓰지 않은 가장 작은 번호의 색을 준다. 빠르지만(O(V+E)) 항상 최소는 아니다 — 순서에 따라 결과가 달라진다.
| 그래프 모양 | χ (색칠수) | 이유 |
|---|---|---|
| 간선이 하나도 없음 | 1 | 아무 제약 없음 |
| 이분 그래프 (짝수 사이클 포함) | 2 | 두 그룹으로 나뉘고 그룹 안엔 간선이 없음 ↔ 홀수 사이클이 없다 |
| 홀수 길이 사이클 (C₃, C₅, …) | 3 | 2색으로 번갈아 칠하면 시작·끝이 만나 충돌 |
| 완전그래프 Kₙ (모두와 연결) | n | 모든 쌍이 이웃이라 전부 다른 색 |
| 평면 그래프 (지도) | ≤ 4 | 4색 정리 — 어떤 지도든 4색이면 충분 (1976년 컴퓨터로 증명) |
χ(G) ≥ ω(G) (가장 큰 완전 부분그래프, 즉 서로 다 이어진 정점 무리의 크기). 그리고 탐욕적 색칠은 χ(G) ≤ Δ(G) + 1 을 보장한다(Δ = 최대 차수). 정확한 χ를 구하는 건 NP-난해 — 큰 그래프에선 근사·휴리스틱을 쓴다. → 백트래킹으로 정확히 풀 수도 있지만 느리다.
탐욕법은 정점을 훑는 순서에 민감하다. 나쁜 순서는 이분 그래프에도 여러 색을 쓰게 만든다(왕관 그래프가 대표적). Welsh–Powell 휴리스틱은 차수가 큰 정점부터 칠한다 — 까다로운 정점을 먼저 처리해서 색 수를 줄이는 경향이 있다. 위 데모의 「탐욕적 색칠」도 차수 내림차순을 쓴다.
# 탐욕적 그래프 색칠 (Welsh–Powell 순서) def greedy_coloring(adj): # adj: {정점: set(이웃)} order = sorted(adj, key=lambda v: -len(adj[v])) # 차수 큰 순 color = {} for v in order: used = {color[u] for u in adj[v] if u in color} c = 0 while c in used: # 이웃이 안 쓴 가장 작은 색 c += 1 color[v] = c return color # max(color.values())+1 = 쓴 색 개수
| 상황 | 정점 | 간선(충돌) | 색 |
|---|---|---|---|
| 시험 시간표 | 과목 | 같은 학생이 듣는 두 과목 | 시험 시간대 |
| 레지스터 배정 | 변수(의 생존 구간) | 동시에 살아 있는 두 변수 | CPU 레지스터 |
| 지도 색칠 | 나라·주 | 국경을 맞댄 두 지역 | 칠하는 색 |
| 무선 주파수 할당 | 기지국 | 전파가 겹치는 두 기지국 | 채널 주파수 |
| 스도쿠 | 81칸 | 같은 행·열·박스의 두 칸 | 숫자 1–9 (χ = 9) |
| 회의실 배정 | 회의 | 시간이 겹치는 두 회의 | 회의실 |