随机文本生成技术---order-k马尔科夫链文本生成技术

这里的k = 2:
   
    int k = 2;
    char inputchars[5000000];
    char *word[1000000];
    int nword = 0;
    首先,扫描整个输入文本来实现算法从而生成每个单词。我们将数组word作为一个指向字母的后缀数组,只是它仅从单词的边界开始。变量nword保存了单词的数目。我们使用下面的代码读取文件:
    word[0] = inputchars
    while scanf("%s", word[nword]) != EOF
        word[nword+1] = word[nword] + strlen(word[nword]) + 1
        nword++
    将文件中的每个单词添加到inputchars中,并通过scanf提供的null字符终止每个单词。
    第二,在读取输入之后,对word数组进行排序,将所有指向同一个k单词序列的指针收集起来。该函数进行了下列比较
    int wordncmp(char *p, char *q)
        n = k;
        for (; *p == *q; p++, q++)
            if (*p == 0 && --n == 0)
                return 0
        return *p - *q
    当字符相同是,它就扫描两个字符串,每次遇到null字符,它就将计算器n减1,并在查找到k个相同的单词后返回0(相同)。当它找到不同的字符时,返回不同(*p - *q)
   
    读取输入之后,在最后的单词后追加k个null字符(这样比较函数就不会超过整个字符串的末端),输出文档的前k个单词(以开始随机输出),并调用排序:
    for i = [0, k)
        word[nword][i] = 0
    for i = [0, k)
        print word[i]
    qsort(word, nword, sizeof(word[0]), sortcmp)
    我们采用的空间上比较高效的数据结构中现在包含了大量关于文本中"K-gram(K链)"信息。如果k为1,并且输入文本为“of the people, by the people, for the people”,word数组如下所示:
    排序前:
    word[0]: of the people,by the people .....
    word[1]: the people,by the people, for ...
    word[2]: people,by the people,for the..
    word[3]: by the people, for the people
    word[4]: the people, for the people
    word[5]: people,for the people
    word[6]: for the people
    word[7]: the people
    word[8]: people
    排序后:
    word[0]: by the people, for the people
    word[1]: for the people
    word[2]: of the people, by the people
    word[3]: people
    word[4]: people, by the people
    word[5]: people, for the people
    word[6]: the people,by the people
    word[7]: the people
    word[8]: the people,for the people
    如果查找“the”后跟的单词,就在后缀数组中查找它,有三个选择:两次"people,"和一次"people"
   
    现在,我们可以使用以下的伪代码来生产没有意义的文本
    phrase = first phrase in input array
    loop
        perform a binary search for phrase in word[0..nword-1] //查找phrase的第一次出现
        for all phrases equal in the first k words  //扫描所有相同的词组,并随机选择其中一个。
            select one at random, pointed to by p
        phrase = word following p
        if k-th word of phrase is length 0 //如该词组的第k个单词的长度为0,表明该词组是文档末尾,结束循环
            break
        print k-th word of phrase
    完整的伪码实现为:
    phrase = inputchars
 for (wordsleft = 10000; wordsleft > 0; wordsleft--)
  l = -1
  u = nword
  while l+1 != u
   m = (l + u) / 2
   if wordncmp(word[m], phrase) < 0
    l = m
   else
    u = m
  for (i = 0; wordncmp(phrase, word[u+i]) == 0; i++)
   if rand() % (i+1) == 0
    p = word[u+i]
  phrase = skip(p, 1)
  if strlen(skip(phrase, k-1)) == 0
   break
  print skip(phrase, k-1) 
生成灰色-马尔科夫链的代码如下所示: ```python import numpy as np def GM11(x0): """ 灰色预测模型GM(1,1)的Python实现 """ x1 = np.cumsum(x0) z1 = (x1[:-1] + x1[1:]) / 2.0 z1 = z1.reshape((len(z1), 1)) B = np.append(-z1, np.ones_like(z1), axis=1) Yn = x0[1:].reshape((len(x0) - 1, 1)) [[a], [b]] = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Yn) return (x0[0] - b / a) * np.exp(-a * np.arange(1, len(x0) + 1)) - (x0[0] - b / a) * np.exp(-a * np.arange(len(x0))) def Markov(data): """ 根据灰色预测结果生成马尔科夫链 """ delta = np.max(data) - np.min(data) p = np.zeros((delta+1, delta+1)) for i in range(len(data)-1): p[int(data[i+1])-int(data[i])][int(data[i])+1] += 1 for i in range(delta+1): if np.sum(p[i,:]) != 0: p[i,:] /= np.sum(p[i,:]) return p ``` 其中,`GM11` 函数实现了灰色预测模型GM(1,1)的计算,`Markov` 函数则根据灰色预测结果生成马尔科夫链。具体使用方法可以参考下面的示例代码: ```python import matplotlib.pyplot as plt # 生成测试数据 x0 = np.array([23, 26, 30, 34, 37, 40, 43, 46, 49, 53]) # 使用灰色预测模型计算预测值 x1 = GM11(x0) # 根据预测值生成马尔科夫链 p = Markov(x1) # 打印预测值和马尔科夫链 print('预测值:', x1) print('马尔科夫链:', p) # 绘制预测值和原始数据的对比图 plt.plot(x0, 'b-o', label='原始数据') plt.plot(x1, 'r-o', label='预测数据') plt.legend() plt.show() ``` 执行上述代码可以得到预测值和马尔科夫链的结果,并且绘制了预测值和原始数据的对比图。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值