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