Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // TransitiveClosure returns a new edge function for the transitive
- // closure of the graph. The algorithm used here is cute, but hardly
- // the most performant but should work well enough on sparse graphs
- func TransitiveClosure(g Graph) map[int][]int {
- edges := make(map[int][]int)
- gSize := g.VertexCount()
- // Make h
- h := simpleGraph{
- vertexCount: gSize * 3,
- edges: make(map[int][]int),
- }
- for v := 0; v < gSize; v++ {
- // 3 vertex path
- h.edges[v+gSize] = []int{v}
- h.edges[v] = []int{v + 2*gSize}
- // Original edges
- for _, u := range g.Edges(v) {
- h.edges[v] = append(h.edges[v], u)
- }
- // Start -> Every Path end
- for u := 0; u < gSize; u++ {
- h.edges[v+gSize] = append(h.edges[v+gSize], u+2*gSize)
- }
- }
- hRed := TransitiveReduction(h)
- for v := 0; v < gSize; v++ {
- ends := make(map[int]bool)
- for _, u := range hRed[v+gSize] {
- // Not an end, so we don't care
- if u < 2*gSize {
- continue
- }
- // v -> u-2*gSize isn't in the transitive closure
- ends[u-2*gSize] = true
- }
- for u := 0; u < gSize; u++ {
- if !ends[u] {
- edges[v] = append(edges[v], u)
- }
- }
- }
- return edges
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement