[TAOCP] 2.2.3 연결된 할당 - 위상정렬

2,379 views

Published on

Published in: Technology, Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,379
On SlideShare
0
From Embeds
0
Number of Embeds
802
Actions
Shares
0
Downloads
7
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

[TAOCP] 2.2.3 연결된 할당 - 위상정렬

  1. 1. [TAOCP]2.2.3 연결된 할당- 위상정렬ohyecloudyhttp://ohyecloudy.com아꿈사http://cafe.naver.com/architect1.cafe2011.04.23
  2. 2. 부분순서위상정렬위상정렬 알고리즘 사용하는 자료구조 알고리즘
  3. 3. http://www.slideshare.net/ohyecloudy/4-3467839
  4. 4. 이항 관계가더 일반적 용어 부분순서는 책에 이항 관계에 대해 이항 관계 부분집합 특별한 언급이 없다.
  5. 5. 다시 책으로…
  6. 6. 부분순서 partial ordering 다음을 만족하는 이항관계만일 ≼ 이고 y ≼ 이면 ≼ . 추이성만일 ≼ 이고 y ≼ 이면 = . 반대칭성 ≼ . 반영성
  7. 7. ≺ 는 ≼ 이고 ≠ 만일 ≺ 이고 y ≺ 이면 ≺ . 추이성 만일 ≺ 이면 ⊀ . 반대칭성 ⊀ . 비반영성
  8. 8. 부분순서위상정렬위상정렬 알고리즘 사용하는 자료구조 알고리즘
  9. 9. 1 3 4 6 7위상 정렬 topological sorting 8 부분순서를 선형적인 순서로 배치 2 5 9 1 3 7 4 9 2 5 8 6
  10. 10. 부분순서위상정렬위상정렬 알고리즘 사용하는 자료구조 알고리즘
  11. 11. 객체 k의 직접immediate 선행자 개수 + 0 COUNT[k] TOP[k] 객체 k의 직접 후행자 목록 시작을 가리키는 링크 ※앞으로 표기를 간단히 한다. +, 0은 생략
  12. 12. 객체 k의 직접 후행자 + 0 SUC NEXT 목록의 다음 항목 ※앞으로 표기를 간단히 한다. +, 0은 생략
  13. 13. 7 ≺ 5, 3 ≺ 7, 9 ≺ 5 k 1 2 3 4 5 6 7 8 9COUNT[k] 2 1 TOP[k] 7 5 5
  14. 14. 왜 이런 구조? 알고리즘 단순화COUNT 필드가 0인 노드 출력 직접 선행자가 없다직접 후행자 COUNT 필드 감소 직접 선행자가 다 출력된 객체를 찾는다
  15. 15. COUNT 필드가 0인 노드 검색 까다로움대기열을 만듬 COUNT 필드가 0인 노드를 연결 COUNT 필드와 QLINK 필드 저장 위치는 같다 헷갈림을 방지하려고 QLINK로 표기 필드에 들어있는 값은 링크를 뜻함
  16. 16. 부분순서위상정렬위상정렬 알고리즘 사용하는 자료구조 알고리즘
  17. 17. T1. 초기화 T2. 다음 관계 T3. 관계 기록T4. 0들을 찾는다 T5. 대기열 앞단 출력 T6. 관계들 삭제 T8. 공정 끝 T7. 대기열에서 제거QLINK[0], COUNT[0]=QLINK[0], … COUNT[N]=QLINK[N]P : 저장소 풀 안의 노드를 참조F, R : 대기열 앞단과 뒷단을 가리키는 데 쓰는 정수 값N : 출력해야 할 남은 객체 개수
  18. 18. T1. 초기화 T2. 다음 관계 T3. 관계 기록T4. 0들을 찾는다 T5. 대기열 앞단 출력 T6. 관계들 삭제 T8. 공정 끝 T7. 대기열에서 제거n 입력 받음.foreach (1≤k≤n) COUNT[k] ← 0, TOP[k] ← ΛN←n
  19. 19. n = 9 가 입력됐다면 N=9 k 1 2 3 4 5 6 7 8 9COUNT[k] 0 0 0 0 0 0 0 0 0 TOP[k] Λ Λ Λ Λ Λ Λ Λ Λ Λ
  20. 20. T1. 초기화 T2. 다음 관계 T3. 관계 기록T4. 0들을 찾는다 T5. 대기열 앞단 출력 T6. 관계들 삭제 T8. 공정 끝 T7. 대기열에서 제거다음 ≺ 를 얻는다.없다면 T4로 고고
  21. 21. T1. 초기화 T2. 다음 관계 T3. 관계 기록T4. 0들을 찾는다 T5. 대기열 앞단 출력 T6. 관계들 삭제 T8. 공정 끝 T7. 대기열에서 제거 ≺ 에서COUNT[k]를 1증가P ⇐ AVAIL, SUC(P) ← k, NEXT(P) ← TOP[j], TOP[j] ← P
  22. 22. 9 ≺ 2 가 입력됐다면 N=9 k 1 2 3 4 5 6 7 8 9COUNT[k] 0 1 0 0 0 0 0 0 0 TOP[k] Λ Λ Λ Λ Λ Λ Λ Λ Λ ≺ 에서 COUNT[k]를 1증가 P ⇐ AVAIL, SUC(P) ← k, NEXT(P) ← TOP[j], TOP[j] ← P
  23. 23. 9 ≺ 2 가 입력됐다면 N=9 k 1 2 3 4 5 6 7 8 9COUNT[k] 0 1 0 0 0 0 0 0 0 TOP[k] Λ Λ Λ Λ Λ Λ Λ Λ Λ P 2 Λ ≺ 에서 COUNT[k]를 1증가 P ⇐ AVAIL, SUC(P) ← k, NEXT(P) ← TOP[j], TOP[j] ← P
  24. 24. 9 ≺ 2 가 입력됐다면 N=9 k 1 2 3 4 5 6 7 8 9COUNT[k] 0 1 0 0 0 0 0 0 0 TOP[k] Λ Λ Λ Λ Λ Λ Λ Λ 2 Λ ≺ 에서 COUNT[k]를 1증가 P ⇐ AVAIL, SUC(P) ← k, NEXT(P) ← TOP[j], TOP[j] ← P
  25. 25. 9 ≺ 2, 3 ≺ 7, 7 ≺ 5, 5 ≺ 8, 8 ≺ 6 N=9 4 ≺ 6, 1 ≺ 3, 7 ≺ 4, 9 ≺ 5, 2 ≺ 8이 입력됐다면 k 1 2 3 4 5 6 7 8 9COUNT[k] 0 1 1 1 2 2 1 2 0 TOP[k] Λ SUC 3 8 7 6 8 4 6 5 NEXT Λ Λ Λ Λ Λ Λ 5 2 Λ Λ
  26. 26. T1. 초기화 T2. 다음 관계 T3. 관계 기록T4. 0들을 찾는다 T5. 대기열 앞단 출력 T6. 관계들 삭제 T8. 공정 끝 T7. 대기열에서 제거출력 대기열을 QLINK 필드를 통해 연결R ← 0, QLINK[0] ← 0foreach (1≤k≤n) if COUNT[k] == 0 then QLINK[R] ← k, R ← kF ← QLINK[0]
  27. 27. QLINK[0] = 0, R = 0, N = 9 k 1 2 3 4 5 6 7 8 9COUNT[k] 0 1 1 1 2 2 1 2 0 TOP[k] Λ SUC 3 8 7 6 8 4 6 5 R ← 0, Λ Λ Λ Λ Λ Λ NEXT QLINK[0] ← 0 foreach (1≤k≤n) 5 if COUNT[k] == 0 then QLINK[R] ← k, R ← k 2 F ← QLINK[0] Λ Λ
  28. 28. QLINK 구분이 쉽게 숫자에 밑줄 QLINK[0] = 1, R = 1, N = 9 k 1 2 3 4 5 6 7 8 9COUNT[k] 0 1 1 1 2 2 1 2 0 TOP[k] Λ SUC 3 8 7 6 8 4 6 5 R ← 0, Λ Λ Λ Λ Λ Λ NEXT QLINK[0] ← 0 foreach (1≤k≤n) 5 if COUNT[k] == 0 then QLINK[R] ← k, R ← k 2 F ← QLINK[0] Λ Λ
  29. 29. QLINK[0] = 1, R = 9, N = 9 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 1 1 2 2 1 2 0 TOP[k] Λ SUC 3 8 7 6 8 4 6 5 R ← 0, Λ Λ Λ Λ Λ Λ NEXT QLINK[0] ← 0 foreach (1≤k≤n) 5 if COUNT[k] == 0 then QLINK[R] ← k, R ← k 2 F ← QLINK[0] Λ Λ
  30. 30. QLINK[0] = 1, F = 1, R = 9, N = 9 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 1 1 2 2 1 2 0 TOP[k] Λ SUC 3 8 7 6 8 4 6 5 R ← 0, Λ Λ Λ Λ Λ Λ NEXT QLINK[0] ← 0 foreach (1≤k≤n) 5 if COUNT[k] == 0 then QLINK[R] ← k, R ← k 2 F ← QLINK[0] Λ Λ
  31. 31. QLINK[0] = 1, F = 1, R = 9, N = 9 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 1 1 22 1 2 0 TOP[k] COUNT가 0인 것들 중 가장 먼저 나온 숫자가Λ F에 들어간다. SUC 3 8 7 6 0인 숫자들은 4 COUNT가 8 6 5 QLINK로 이어져 있음 R ← 0, Λ Λ Λ Λ Λ Λ NEXT QLINK[0] ← 0 foreach (1≤k≤n) 1→9 5 if COUNT[k] == 0 then QLINK[R] ← k, R ← k 2 F ← QLINK[0] Λ Λ
  32. 32. T1. 초기화 T2. 다음 관계 T3. 관계 기록T4. 0들을 찾는다 T5. 대기열 앞단 출력 T6. 관계들 삭제 T8. 공정 끝 T7. 대기열에서 제거F 출력if F == 0 goto T8else N ← N – 1, P ← TOP[F]
  33. 33. 출력 : 1 QLINK[0] = 1, F = 1, R = 9, N = 9 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 1 1 2 2 1 2 0 TOP[k] Λ SUC 3 8 7 6 8 4 6 5 NEXT Λ Λ Λ Λ Λ ΛF 출력, if (F == 0) { goto T8 } else { N ← N – 1, P ← TOP[F] } 5 2 Λ Λ
  34. 34. 출력 : 1 QLINK[0] = 1, F = 1, R = 9, N = 8 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 1 1 2 2 1 2 0 TOP[k] Λ P SUC 3 8 7 6 8 4 6 5 NEXT Λ Λ Λ Λ Λ ΛF 출력, if (F == 0) { goto T8 } else { N ← N – 1, P ← TOP[F] } 5 2 Λ Λ
  35. 35. 출력 : 1 QLINK[0] = 1, F = 1, R = 9, N = 8 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 1 1 2 2 1 2 0 TOP[k] Λ 이 단계에서만 출력이 이루어짐 P 출력한 숫자 직접 후행자를 P로 지정하고 계속 진행 SUC 3 8 7 6 8 4 6 5 뒤에 단계에서 다음에 NEXT Λ Λ Λ 숫자를 Λ 넣는다. 출력할 Λ F에 ΛF 출력, if (F == 0) { goto T8 } else { N ← N – 1, P ← TOP[F] } 5 2 Λ Λ
  36. 36. T1. 초기화 T2. 다음 관계 T3. 관계 기록T4. 0들을 찾는다 T5. 대기열 앞단 출력 T6. 관계들 삭제 T8. 공정 끝 T7. 대기열에서 제거loop if P == Λ goto T7 else COUNT[SUC(P)] = COUNT[SUC(P)] – 1, if COUNT[SUC(P)] == 0 QLINK[R] ← SUC(P), R ← SUC(P) P ← NEXT(P)
  37. 37. 출력 : 1 QLINK[0] = 1, F = 1, R = 9, N = 8 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 0 1 2 2 1 2 0 TOP[k] Λ P SUC 3 8 7 6 8 4 6 5 NEXT Λ Λ Λ Λ Λ Λ loop { if (P == Λ) {goto T7} else { COUNT[SUC(P)]--, 5 2 Λ Λ if (COUNT[SUC(P)] == 0) {QLINK[R] ← SUC(P), R ← SUC(P)} P ← NEXT(P) }
  38. 38. 출력 : 1 QLINK[0] = 1, F = 1, R = 3, N = 8 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 0 1 2 2 1 2 3 TOP[k] Λ P SUC 3 8 7 6 8 4 6 5 NEXT Λ Λ Λ Λ Λ Λ loop { if (P == Λ) {goto T7} else { COUNT[SUC(P)]--, 5 2 Λ Λ if (COUNT[SUC(P)] == 0) {QLINK[R] ← SUC(P), R ← SUC(P)} P ← NEXT(P) }
  39. 39. 출력 : 1 QLINK[0] = 1, F = 1, R = 3, N = 8 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 0 1 2 2 1 2 3 TOP[k] Λ P SUC 3 8 7 6 8 4 6 5 NEXT Λ Λ Λ Λ Λ Λ loop { if (P == Λ) {goto T7} else { COUNT[SUC(P)]--, 5 2 Λ Λ if (COUNT[SUC(P)] == 0) {QLINK[R] ← SUC(P), R ← SUC(P)} P ← NEXT(P) }
  40. 40. 출력 : 1 QLINK[0] = 1, F = 1, R = 3, N = 8 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 출력한 숫자의 직접 후행자들 1 0 1 2 2 2 3 COUNT를 감소 TOP[k] Λ (COUNT는 직접 선행자 개수) P 1 ≺ 3, 1 ≺ 5 가 있고 SUC 3 8 71을 출력했다면 3, 5의 6 8 4 6 5 직접 선행자 개수를 줄인다 NEXT Λ Λ Λ Λ Λ Λ 출력한 숫자 뒷정리라 생각하면 됨 loop { if (P == Λ) {goto T7} else { COUNT[SUC(P)]--, 5 2 Λ Λ if (COUNT[SUC(P)] == 0) {QLINK[R] ← SUC(P), R ← SUC(P)} P ← NEXT(P) }
  41. 41. T1. 초기화 T2. 다음 관계 T3. 관계 기록T4. 0들을 찾는다 T5. 대기열 앞단 출력 T6. 관계들 삭제 T8. 공정 끝 T7. 대기열에서 제거F ← QLINK[F], goto T5
  42. 42. 출력 : 1 QLINK[0] = 1, F = 3, R = 3, N = 8 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 0 1 2 2 1 2 3 TOP[k] Λ P SUC 3 8 7 6 8 4 6 5 NEXT Λ Λ Λ Λ Λ Λ F ← QLINK[F], goto T5 5 2 Λ Λ
  43. 43. 출력 : 1 QLINK[0] = 1, F = 3, R = 3, N = 8 k 1 2 3 4 5 6 7 8 9COUNT[k] 9 1 앞0 단계에서 직접2 1 선행자가 0인1 2 2 3 TOP[k] 숫자를 QLINK로 연결 Λ P 여기선 QLINK를 따라가며 다음에 출력할 숫자를 F에 넣는다 SUC 3 8 7 6 8 4 6 5 NEXT Λ Λ Λ Λ 따라 가는거니 QLINK는 Λ Λ 헷갈리지 말 것. F ← QLINK[F], goto T5 5 2 Λ Λ

×