-
Notifications
You must be signed in to change notification settings - Fork 1
/
markov.py
82 lines (64 loc) · 1.82 KB
/
markov.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import random
def intMarkov1(seq):
matrix = dict()
for i in range(len(seq)-1):
n1 = seq[i]
n2 = seq[i+1]
if(n1 in matrix):
if(n2 in matrix[n1]):
matrix[n1][n2] += 1
else:
matrix[n1][n2] = 1
else:
matrix[n1] = {n2: 1}
return matrix
def intMarkovN(seq, n, wrap):
m = max(seq)
matrix = {-1:{n:m}}
if(wrap):
seq += seq[:n]
for i in range(len(seq)-n):
p = intEncode([seq[i+j] for j in range(n)], m)
q = seq[i+n]
if(p in matrix):
if(q in matrix[p]):
matrix[p][q] += 1
else:
matrix[p][q] = 1
else:
matrix[p] = {q: 1}
return matrix
#g = list of ints to be encoded, m = largest int
def intEncode(g, m):
return sum([g[i]*(m+1)**i for i in range(len(g))])
#e = encoded int, n = number of ints in list
def intDecode(e, m, n):
out = []
for i in range(n):
out.append(e % (m+1))
e = e//(m+1)
return out
def nextRandom(p):
if(len(p) == 0):
return None
r = random.uniform(0, sum(p.values()))
for k in p:
r -= p[k]
if(r < 0.0001):
break
return k
def generate(start, matrix, l, report=False):
if report:
print("Markov entries: %d" % len(matrix))
out = start
n = [k for k in matrix[-1]][0]
m = matrix[-1][n]
if(len(start) != n):
return None
for i in range(l-n):
out += [nextRandom(matrix[intEncode(out[-n:],m)])]
return out
def autoGenerate(seq, l, n, report=False):
if report:
print("Sequence length: %d" % len(seq))
return generate(seq[:n], intMarkovN(seq, n, True), l, report)