Advertisement
Guest User

Untitled

a guest
Sep 11th, 2019
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 1.14 KB | None | 0 0
  1. // TransitiveClosure returns a new edge function for the transitive
  2. // closure of the graph. The algorithm used here is cute, but hardly
  3. // the most performant but should work well enough on sparse graphs
  4. func TransitiveClosure(g Graph) map[int][]int {
  5.     edges := make(map[int][]int)
  6.     gSize := g.VertexCount()
  7.     // Make h
  8.     h := simpleGraph{
  9.         vertexCount: gSize * 3,
  10.         edges:       make(map[int][]int),
  11.     }
  12.     for v := 0; v < gSize; v++ {
  13.         // 3 vertex path
  14.         h.edges[v+gSize] = []int{v}
  15.         h.edges[v] = []int{v + 2*gSize}
  16.         // Original edges
  17.         for _, u := range g.Edges(v) {
  18.             h.edges[v] = append(h.edges[v], u)
  19.         }
  20.         // Start -> Every Path end
  21.         for u := 0; u < gSize; u++ {
  22.             h.edges[v+gSize] = append(h.edges[v+gSize], u+2*gSize)
  23.         }
  24.     }
  25.     hRed := TransitiveReduction(h)
  26.     for v := 0; v < gSize; v++ {
  27.         ends := make(map[int]bool)
  28.         for _, u := range hRed[v+gSize] {
  29.             // Not an end, so we don't care
  30.             if u < 2*gSize {
  31.                 continue
  32.             }
  33.             // v -> u-2*gSize isn't in the transitive closure
  34.             ends[u-2*gSize] = true
  35.         }
  36.         for u := 0; u < gSize; u++ {
  37.             if !ends[u] {
  38.                 edges[v] = append(edges[v], u)
  39.             }
  40.         }
  41.     }
  42.     return edges
  43. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement