user: 위상 정렬이란 무엇인가?

gpt: **위상 정렬**은 유향 그래프의 꼭짓점들을 변의 방향을 거스르지 않도록 나열하는 것을 의미한다. 위상정렬을 가장 잘 설명해 줄 수 있는 예로 대학의 선수과목 구조를 예로 들 수 있다. 만약 특정 수강과목에 선수과목이 있다면 그 선수 과목부터 수강해야 하므로, 특정 과목들을 수강해야 할 때 위상 정렬을 통해 올바른 수강 순서를 찾아낼 수 있다. 이와 같이 선후 관계가 정의된 그래프 구조 상에서 선후 관계에 따라 정렬하기 위해 위상 정렬을 이용할 수 있다. 정렬의 순서는 유향 그래프의 구조에 따라 여러 개의 종류가 나올 수 있다. 위상 정렬이 성립하기 위해서는 반드시 그래프의 순환이 존재하지 않아야 한다. 즉, 그래프가 비순환 유향 그래프여야 한다.

일반적인 위상 정렬의 적용은 주로 업무의 일정을 일어나야 할 순서에 따라 배치하기 위하는 것으로, 이 알고리즘은 프로젝트 관리 기법을 평가 및 분석하기 위한 기법에 적용하기 위한 목적을 위해 1960년대 초반부터 연구되었다 . 이 때, 해당 업무는 꼭짓점으로 표현되었고, 각 꼭짓점을 연결하는 변은 해당 업무 간의 선후 관계를 표현하였다. 가령, 옷을 다리기 위한 업무는 반드시 옷을 세탁기에 돌리는 업무 뒤에 배치되어야 한다. 이와 같이, 위상정렬은 각 업무를 수행하기 위한 순서를 제공하였다.

Topological sorting은 컴퓨터 과학에서, 방향 그래프의 위상 정렬 또는 위상 배치는 정점의 선형 순서이다. 꼭짓점 u에서 꼭짓점 v로의 모든 방향 꼭짓점 uv는 v의 순서 전에 u가 오는 것이다. 예를 들어, 그래프의 꼭짓점은 아마 수행하는 일은 대표한다. 그리고 꼭짓점은 어떤 일이 다른 것보다 먼저 수행되어야 하는 허가되지 않은 것을 대표한다. 이러한 것에서, 위상 배열은 일의 유용한 순서에 불과하다. 정확히 위상 정렬은 모든 종속성을 방문한 후에만 각 노드 v를 방문하는 그래프 순환이다. 위상 배열은 가능하다. 정말 만약에 그래프 방향이 없는 순환이라면, 아마 그것은 방향 순환 그래프일 것이다. 어떤 DAG는 최소 하나의 위상 배열을 가지고 있다. 그리고 알고리즘은 어떤 DAG 속 선형 시간의 위상 배열이 구성한다고 알려져 있다. 위상 정렬은 feedback arc set 와 같은 랭킹 문제를 해결하는데 많이 사용된다. 위상 정렬은 심지어 DAG의 요소가 연결되지 않을지라도 가능하다.

user: 알고리즘에 대해서도 설명해 줘.

gpt: 위상 정렬의 일반적인 알고리즘은 꼭짓점의 양수 노드의 선형 실행 시간을 가진다.

## Kahn의 알고리즘
Kuhn의 알고리즘과 헷갈리지 않도록 주의!
위상 정렬 알고리즘 중 하나이다. Kahn에 의해 1962년에 처음으로 언급되었다. 궁극적인 위상 정렬로써 같은 순서 속에 일은 꼭짓점에 의해 선택된다. 처음으로, “시작 노드”를 찾는다. 꼭짓점과 연결되지 않고, S집합에 연결되어 있는; 적어도 하나의 노드는 비어있지 않은 순환 그래프 안에 존재한다.

''L'' ← Empty list that will contain the sorted elements
 ''S'' ← Set of all nodes with no incoming edge

 **while** ''S'' **is not** empty **do**
 remove a node ''n'' from ''S''
 add ''n'' to ''L''
 **for each** node ''m'' with an edge ''e'' from ''n'' to ''m'' **do**
 remove edge ''e'' from the graph
 **if** ''m'' has no other incoming edges **then**
 insert ''m'' into ''S''

 **if** ''graph'' has edges **then**
 **return** error ''''
 **else**
 **return** ''L'' ''''

만약 그래프가 DAG라면, 해결책은 L 리스트 안에서 억제하는 것이다.
마찬가지로, 그래프는 적어도 하나의 순환을 가지고 있어야 한다. 그러므로 위상 정렬은 불가능하다.
결과적으로 정렬의 특별하지 않은 것을 반영하여, 구조 S는 Set 또는 queue 또는 stack으로 간단화 할 수 있다. 순서에 의해, 노드 n들은 집합 S로부터 제거된다. 그리고 다른 해결책을 생성한다. kahn의 알고리즘의 변형은 연병렬 스케줄링 및 계층 그래프 그리기를 위한 Coffman-Graham 알고리즘의 핵심 구성 요소를 사전식으로 연결을 끊는다.

## 깊이 우선 탐색
위상 정렬의 대체 가능한 대안 알고리즘은 깊이 우선 탐색을 기반으로 한다. 알고리즘의 임의적인 순서 속 그래프의 각 노드를 통한 루트는 그것이 이미 시작 이후로 거쳐간 노드의 위상 정렬 또는 꼭짓점을 가지지 않은 다른 노드를 건들 때 착수한 깊이 우선 탐색이 제거한다.

 ''L'' ← Empty list that will contain the sorted nodes
 **while** exists nodes without a permanent mark **do**
 select an unmarked node ''n''
 visit

 **function** visit
 **if** ''n'' has a permanent mark **then**
 **return**
 **if** ''n'' has a temporary mark **then**
 **stop** ''''

 mark ''n'' with a temporary mark

 **for each** node ''m'' with an edge from ''n'' to ''m'' **do**
 visit

 remove temporary mark from ''n''
 mark ''n'' with a permanent mark
 add ''n'' to head of ''L''

각 노드 n은 출력 리스트 L에서 모든 다른 노드를 고려한 후에 n에 의존한다. 특히 알고리즘이 노드 n을 추가할 때, 우리는 모든 노드가 n에 의존한다는 것을 보장하는 것은 이미 출력 리스트 L에 있다는 것이다. : 그들은 되풀이 되는 방문 호출에 의해 n에 방문하기 전에 끝나거나, n이 호출되기 전에 끝나는 것 둘 다 L에 추가한다. 각 꼭짓점과 노드가 하나를 방문한 이래로, 알고리즘은 선형 시간에서 실행한다. 그리고 깊이 우선 탐색의 기초 알고리즘은 Cormen et al에 의해 2001년에 만들어진다. 그것은 1976년 Tarjan 인쇄에서 처음 만들어져 온 것처럼 보인다.

## Parallel 알고리즘
Parallel의 랜덤 접속 기계에 의하면, 위상 배치는 ''O''(log을 넣는다. 이를 수행하는 한 가지 방법은 주어진 그래프, 논리적 시간의 인접 행렬을 반복적으로 제곱하는 것이다. 결과 행렬은 가장 긴 길이가 그래프에서 줄어들게 만든다. 꼭짓점을 정렬하는 것은 그들의 가장 긴 방법의 길이에 의해 위상 배치를 생성한다.