You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
2.5 KiB

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "strconv"
  6. "strings"
  7. )
  8. type Markov struct{}
  9. type State struct {
  10. Word string
  11. Count int
  12. Prob float64
  13. NextStates []State
  14. }
  15. var markov Markov
  16. func addWordToStates(states []State, word string) ([]State, int) {
  17. iState := -1
  18. for i := 0; i < len(states); i++ {
  19. if states[i].Word == word {
  20. iState = i
  21. }
  22. }
  23. if iState >= 0 {
  24. states[iState].Count++
  25. } else {
  26. var tempState State
  27. tempState.Word = word
  28. tempState.Count = 1
  29. states = append(states, tempState)
  30. iState = len(states) - 1
  31. }
  32. return states, iState
  33. }
  34. func calcMarkovStates(words []string) []State {
  35. var states []State
  36. //count words
  37. for i := 0; i < len(words)-1; i++ {
  38. var iState int
  39. states, iState = addWordToStates(states, words[i])
  40. if iState < len(words) {
  41. states[iState].NextStates, _ = addWordToStates(states[iState].NextStates, words[i+1])
  42. }
  43. }
  44. //count prob
  45. for i := 0; i < len(states); i++ {
  46. states[i].Prob = (float64(states[i].Count) / float64(len(words)) * 100)
  47. for j := 0; j < len(states[i].NextStates); j++ {
  48. states[i].NextStates[j].Prob = (float64(states[i].NextStates[j].Count) / float64(len(words)) * 100)
  49. }
  50. }
  51. fmt.Println("total words computed: " + strconv.Itoa(len(words)))
  52. //fmt.Println(states)
  53. return states
  54. }
  55. func textToWords(text string) []string {
  56. s := strings.Split(text, " ")
  57. words := s
  58. return words
  59. }
  60. func (markov Markov) train(text string) []State {
  61. words := textToWords(text)
  62. states := calcMarkovStates(words)
  63. //fmt.Println(states)
  64. return states
  65. }
  66. func getNextMarkovState(states []State, word string) string {
  67. iState := -1
  68. for i := 0; i < len(states); i++ {
  69. if states[i].Word == word {
  70. iState = i
  71. }
  72. }
  73. if iState < 0 {
  74. return "word no exist on the memory"
  75. }
  76. var next State
  77. next = states[iState].NextStates[0]
  78. next.Prob = rand.Float64() * states[iState].Prob
  79. for i := 0; i < len(states[iState].NextStates); i++ {
  80. if (rand.Float64()*states[iState].NextStates[i].Prob) > next.Prob && states[iState-1].Word != states[iState].NextStates[i].Word {
  81. next = states[iState].NextStates[i]
  82. }
  83. }
  84. return next.Word
  85. }
  86. func (markov Markov) generateText(states []State, initWord string, count int) string {
  87. var generatedText []string
  88. word := initWord
  89. generatedText = append(generatedText, word)
  90. for i := 0; i < count; i++ {
  91. word = getNextMarkovState(states, word)
  92. generatedText = append(generatedText, word)
  93. }
  94. generatedText = append(generatedText, ".")
  95. text := strings.Join(generatedText, " ")
  96. return text
  97. }