Advertisement
Guest User

min

a guest
May 20th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.67 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "github.com/skorobogatov/input"
  5.     "fmt"
  6.     "math/rand"
  7. )
  8.  
  9. // Φ π δ
  10.  
  11. type Automat struct{
  12.     n, m, q0 int
  13.     Δ [][]int
  14.     Φ [][]string
  15. }
  16.  
  17. func main(){
  18.     var a Automat
  19.     var v int
  20.     var st string
  21.     input.Scanf("%d%d%d", &a.n, &a.m, &a.q0)
  22.     a.Φ, a.Δ = make([][]string, a.n), make([][]int, a.n)
  23.     for j, d := range a.Δ {
  24.         d = make([]int, a.m)
  25.         for i := 0; i < a.m; i++{
  26.             input.Scanf("%d", &v)
  27.             d[i] = v
  28.         }
  29.         a.Δ[j] = d
  30.     }
  31.     for j, f := range a.Φ {
  32.         f = make([]string, a.m)
  33.         for i := 0; i < a.m; i++{
  34.             input.Scanf("%s", &st)
  35.             f[i] = st
  36.         }
  37.         a.Φ[j] = f
  38.     }
  39.     // a = a.Canonise()
  40.     a.AufenkampHohn()
  41.     a.Canonise()
  42.  
  43.     fmt.Println("digraph {\n\trankdir = LR\n\tdummy [label = \"\", shape = none]")
  44.     for i := 0; i < a.n; i++{
  45.         fmt.Println("\t", i, "[shape = circle]")
  46.     }
  47.  
  48.     fmt.Println("\tdummy -> ", a.q0)
  49.     for i, t := range a.Δ{
  50.         for j, s := range t {
  51.             fmt.Printf("\t%d -> %d [label = \"%s(%s)\"]\n",
  52.                             i, s, string(rune(97+j)), a.Φ[i][j])
  53.         }
  54.     }
  55.     fmt.Println("}")
  56. }
  57.  
  58. func (a *Automat) Canonise() {
  59.     used := make([]int, a.n)
  60.     for i := 0; i < a.n; i++ {
  61.         used[i] = -1
  62.     }
  63.     TNew := make([][]int, a.n)
  64.     for i := range TNew {
  65.         TNew[i] = make([]int, a.m)
  66.     }
  67.     SNew := make([][]string, a.n)
  68.     for i := range SNew {
  69.         SNew[i] = make([]string, a.m)
  70.     }
  71.     index := 0
  72.     index = DFS(used, a.Δ, a.q0, &index, a.m)
  73.     for i := 0; i < a.n; i++ {
  74.         if used[i] != -1 {
  75.             SNew[used[i]] = a.Φ[i]
  76.             for j := 0; j < a.m; j++ {
  77.                 TNew[used[i]][j] = used[a.Δ[i][j]]
  78.             }
  79.         }
  80.     }
  81.     a.n, a.Δ, a.Φ, a.q0, a.m = index, TNew[0:index], SNew[0:index], 0, a.m
  82. }
  83.  
  84. func DFS(used []int, arr [][]int, begin int, index *int, m int) int {
  85.     used[begin] = *index
  86.     (*index)++
  87.     for i := 0; i < m; i++ {
  88.         if used[arr[begin][i]] == -1 {
  89.             *index = DFS(used, arr, arr[begin][i], index, m)
  90.         }
  91.     }
  92.     return (*index)
  93. }
  94.  
  95.  
  96. func (a *Automat) AufenkampHohn() {
  97.     π := make([]int, a.n)
  98.     m1, m2 := -1, -1;
  99.     m1, π = a.Split1()
  100.     for m1 != m2 {
  101.         m2 = m1
  102.         m1, π = a.Split(π)
  103.     }
  104.     help1, help2 := make([]int, a.n), make([]int, a.n)
  105.     for i, j := 0, 0; i < a.n; i++ {
  106.         if π[i] == i {
  107.             help2[j] = i
  108.             help1[i] = j
  109.             j++
  110.         }
  111.     }
  112.     a.n = m1
  113.     a.q0 = help1[π[a.q0]]
  114.     p := make([][]string, a.n)
  115.     for i := 0; i < a.n; i++ {
  116.         p[i] = make([]string, a.m)
  117.     }
  118.     for i := 0; i < a.n; i++ {
  119.         for j := 0; j < a.m; j++ {
  120.             a.Δ[i][j] = help1[π[a.Δ[help2[i]][j]]]
  121.             p[i][j] = a.Φ[help2[i]][j]
  122.         }
  123.     }
  124.     a.Φ = p
  125. }
  126.  
  127. func (a Automat) Split(π []int) (int, []int) {
  128.     m := a.n
  129.     arr := make([]int, m)
  130.     for i := range arr {
  131.         arr[i] = i
  132.     }
  133.     for i := 0; i < a.n; i++ {
  134.         for j := i + 1; j < a.n; j++ {
  135.             if π[i] == π[j] && Find(arr, i) != Find(arr, j) {
  136.                 eq := true
  137.                 for k := 0; k < a.m; k++ {
  138.                     if π[a.Δ[i][k]] != π[a.Δ[j][k]] {
  139.                         eq = false
  140.                         break
  141.                     }
  142.                 }
  143.                 if eq {
  144.                     Union(&arr, i, j)
  145.                     m--
  146.                 }
  147.             }
  148.         }
  149.     }
  150.     for i := 0; i < a.n; i++{
  151.         π[i] = Find(arr, i)
  152.     }
  153.     return m, π
  154. }
  155.  
  156. func (a Automat) Split1() (int, []int) {
  157.     π := make([]int, a.n)
  158.     q := a.n
  159.     arr := make([]int, q)
  160.     for i := range arr{
  161.         arr[i] = i
  162.     }
  163.     for i := 0; i < a.n; i++ {
  164.         for j := i + 1; j < a.n; j++ {
  165.             if Find(arr, i) != Find(arr, j) {
  166.                 eq := true
  167.                 for k := 0; k < a.m; k++ {
  168.                     if a.Φ[i][k] != a.Φ[j][k] {
  169.                         eq = false
  170.                         break
  171.                     }
  172.                 }
  173.                 if eq {
  174.                     Union(&arr, i, j)
  175.                     q--
  176.                 }
  177.             }
  178.         }
  179.     }
  180.     for i := 0; i < a.n; i++ {
  181.         π[i] = Find(arr, i)
  182.     }
  183.     return q, π
  184. }
  185.  
  186. func Union(a *[]int, x int, y int) {
  187.     x_, y_ := Find(*a, x), Find(*a, y)
  188.     if x_ == y_{
  189.         return
  190.     }
  191.     if rand.Int() % 2 == 1 {
  192.         x_, y_ = y_, x_
  193.     }
  194.     (*a)[y_] = x_
  195. }
  196.  
  197. func Find(a []int, x int) int {
  198.     if a[x] == x {
  199.         return x
  200.     } else {
  201.         a[x] = Find(a, a[x])
  202.     }
  203.     return a[x]
  204. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement