[TIL][Tue] 위상정렬 Topological Sorting

2023. 10. 24. 22:36· 공부기록/Algorithm
목차
  1. 주요 개념
  2. 왜 중요한가?

학습 자료 (레퍼런스)

https://www.youtube.com/watch?v=xeSz3pROPS8

https://www.geeksforgeeks.org/topological-sorting/

위상정렬

  • 그래프 정점의 선형적 정렬(ordering)으로, vertex U에서 V로 가는 방향성이 유지된 채 정렬되는 것. 즉, U가 V를 가리킨다면(향한다면) 위상정렬 시 U는 언제나 V보다 먼저 등장해야 한다. 왜냐하면 U를 거쳐야 V를 갈 수 있기 떄문이다.
  • 방향성이 있고 싸이클이 없는 그래프인 DAG(directed acycled graph) 에서만 가능하다.
  • 선형 시간 복잡도를 보임 (O(V+E))
  • 결과물은 unique하지 않다. (레벨간의 순서 stable은 보장하지만, 결과물이 언제나 동일하지 않다.)
  • 이 과업task을 먼저 끝내야 다음을 실행할 수 있는 과업인 선행과업(prerequisites)을 끝내야만 실행되는 업무들, 즉 각자 dependency(의존성)이 있는 업무/과제/과업을 스케쥴링하는 데에 사용된다. ex) 선수과목 수업을 듣기 등의 상황.

주요 개념

  • DAG(Directed Acycling Graph)
  • 진입계수(indegree)
  • 진출계수(outdegree)
  • dependecy

왜 중요한가?

의존성을 가지는 task에서 중요하다. 예를 들자면, 파일이 정확한 순서로 컴파일되었는지 보장하는 빌드 시스템, 과업 스케쥴링, 선수과목, job 스케쥴링….

  • chat GPT says…
    • Build Systems: Ensuring that source files are compiled in the correct order.
    • Task Scheduling: Executing tasks in parallel while respecting dependencies.
    • Course Prerequisites: Planning the order in which courses should be taken.
    • Job Scheduling: Optimizing the execution of jobs on a computer cluster.

DFS(깊이 우선 탐색 접근)(Stack 사용)

Topological Sorting with examples | Topological Sorting using DFS | Imp For Placements & Comp. Exams

DFS를 recursive하게 접근하여 푼다.

import sys

V, E=list(map(int, sys.stdin.readline().strip().split()))
graph=[[] for _ in range(V+1)]
indegree=[0]*(V+1)
for i in range(E):
    sp, ep=list(map(int, sys.stdin.readline().strip().split()))
    graph[sp].append(ep)

    
def topo_sorting(graph):
    stack=[]
    visited=[False]*(V+1)
    
    #DFS - recursion
    def DFS(vertex):
        visited[vertex]=True
        
        for vtx in graph[vertex]:
            if not visited[vtx]:
                DFS(vtx)
                
        stack.append(vertex)
 
    for vtx in range(1, V):
        if not visited[vtx]:
            DFS(vtx)
    
    #거꾸로 리턴한다.
    return stack[::-1]

print(topo_sorting(graph))

Kahn's Algorithm (Queue 사용)

  • 큰 그래프에서 사용하기 유용하다.
from collections import deque
import sys
'''
7 8
1 2
1 5
2 3
2 6
3 4
4 7
5 6
6 4
'''

#노드와 간선 받기
V, E=list(map(int, sys.stdin.readline().strip().split()))

####################
# 그레프/테이블 세팅#
####################

#### 그래프 세팅
# 각 노드마다 이 노드에서 향하는 목적지들이 담긴 리스트를 넣을 준비를 한다. 
# [[2,3], [4, 5]...]
# 0 은 안 쓰고 인덱스1부터 써야 하니까 갯수는 V+1로 세팅.
graph=[[] for _ in range(V+1)]

#### 진입 차수 테이블 세팅
#진입차수테이블 세팅 동적으로 값이 바뀌며 
# 진입차수가 0인 것들은 큐에 넣고, 
# 큐에 넣은 그 것들을 불러와 그 노드와 연결된, 
# 그 노드로부터 출발하는 간선을 타고 가 지워 주어야 한다.
indegree=[0]*(V+1)

#edge를 받아 그래프와 진입 차수 테이블에 세팅한다 .
for _ in range(E):
    sp, ep=list(map(int, sys.stdin.readline().strip().split()))
    graph[sp].append(ep) #도착점 삽입
    indegree[ep]+=1 #진입차수를 넣어줌

####################
# 위상정렬 함수 세팅#
####################

def topology_sort(graph, indegree):
    q=deque()
    res=[]

    #진입 차수가 0인 노드를 큐에 삽입 
    #먼저 살펴봐야 하는 노드들.
    for i in range(1, V+1):
        if indegree[i]==0:
            q.append(i) #넣을 때 순서는 상관이 없으니까 append해도 됨.
                
    while q: #큐에 진입 차수가 0인 vertex가 존재하는 동안 반복한다.
        
        now=q.popleft() #현재 작업중인 vertex
        res.append(now)

        for v in graph[now]:
            indegree[v]-=1
            #뺴고 나서 새로 진입 차수가 0이 되면 큐에 삽입
            if indegree[v]==0:
                q.append(v)
    return res

ans=topology_sort(graph, indegree)
print(*ans, sep=',')

'공부기록 > Algorithm' 카테고리의 다른 글

[TIL][Thu] 동적 계획법 Dynamic Programing  (0) 2023.10.26
[TIL][Wed] 최단거리 알고리즘_다익스트라/플로이드 워셜  (1) 2023.10.25
[TIL][Sat] BFS / DFS in Graph  (1) 2023.10.21
[TIL][Fri] 스택 / 큐  (0) 2023.10.20
[TIL][TUE] 병합정렬/퀵정렬  (1) 2023.10.17
  1. 주요 개념
  2. 왜 중요한가?
'공부기록/Algorithm' 카테고리의 다른 글
  • [TIL][Thu] 동적 계획법 Dynamic Programing
  • [TIL][Wed] 최단거리 알고리즘_다익스트라/플로이드 워셜
  • [TIL][Sat] BFS / DFS in Graph
  • [TIL][Fri] 스택 / 큐
J융
J융
Recording of development
J융
Develop day by day
J융
전체
오늘
어제
  • 분류 전체보기 (67)
    • 공부기록 (63)
      • CS (8)
      • OS (15)
      • Algorithm (19)
      • Web (3)
      • HTML&CSS (6)
      • Electron (1)
      • JavaScript (5)
      • Network (0)
      • C (2)
      • Python (3)
      • Git (1)
    • 개발일기 (3)
      • Alice기록 (0)
      • Krafton Jungle 기록 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • pintos
  • CG
  • 개발일기
  • 비전공자개발자
  • 엘리스AI트랙
  • fe
  • 부트캠프
  • Web
  • 정글공부키워드
  • cs기초
  • 수강후기
  • 크래프톤정글
  • #cs기초
  • 알고리즘
  • 기술면접대비
  • os
  • vm
  • JS기초
  • 앨리스트랙
  • cs지식

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
J융
[TIL][Tue] 위상정렬 Topological Sorting
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.