그래프가 비 주기적이라는 사실은이 문제를 훨씬 간단하게 만듭니다.
토폴로지 종류의 우리에게 정점의 순서를 줄 수는 등,이 경우 내가 < j는 , 그때부터 더 에지가없는 V의 J에 다시 V 전 . 모든 모서리가 목록에서 "앞으로"이동할 수 있도록 정점을 나열했습니다.v1,v2,…,vni<jvjvi
(분석을 수정하고 약간 더 빠른 알고리즘을 제공하도록 편집 됨)
이제 마지막 정점 에서 시작하여이리스트를 거꾸로 돌아갑니다 . v n 의 전이 폐쇄는 그 자체입니다. 또한 추가 브이 N을 행 에지와 각 정점의 전이 폐쇄 V N .vnvnvnvn
서로 버텍스를 들어 최종 뒤쪽에서가는 첫번째 추가 V 나는 자신의 이적 폐쇄, 다음의 전이 폐쇄에 모든 것을 추가 V 난 에 가장자리 정점 모두의 전이 폐쇄 V 전 .vivivivi
최악의 경우 실행 시간은 이며, n 은 꼭짓점 수이고 m ∈ O ( n 2 ) 는 가장자리 수입니다. 위상 정렬에는 시간 O ( n + m ) 가 걸립니다 . 그런 다음 우리는 역방향 패스에서 또 다른 O ( m n ) 작업을 수행합니다. 우리는 목록을 거꾸로 가면서 각 모서리에 대해 최대 n 을 더해야합니다.O(n+m+nm)=O(n3)nm∈O(n2)O(n+m)O(mn)n 누군가의 전이 폐쇄에 대한 정점.
비트 배열로 모든 사람의 전 이적 클로저를 나타내면 상수가 빠르게 향상 될 수 있습니다. 만 가지고 있다고 가정하십시오 . 당신은 비트 단일 64 비트 INT 사용하는 것이 내가 경우 1 내가 그렇지 않으면 내 전이 폐쇄 및 0입니다. 그러면 i 의 전이 클로저에있는 모든 것을 j 에 추가하는 부분 이 정말 빠릅니다. c j | = c i 만 취 합니다. (이진 OR 연산)n=64iiijcjci
들어 , 당신은 배열에 보관하고 약간의 계산을해야 할 것이다, 그러나 그것은 훨씬 더 빨리 객체 세트보다 것이다.n>64
Also, I know the big-O in the very worst case is still O(n3), but to beat this in practice you'd have to have something much more complex. This algorithm also does very well on sparse graphs.