作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4335810.html

一个例子:

韦小宝使用骰子进行游戏,他有两种骰子一种正常的骰子,还有一种不均匀的骰子,来进行出千。

开始游戏时他有2/5的概率出千。

对于正常的骰子A,每个点出现的概率都是1/6.

对于不均匀的骰子B,5,6两种出现的概率为3/10,其余为1/10.

出千的随机规律如下图所示:

我们观测到的投掷结果为:ob={1,3,4,5,5,6,6,3,2,6}

请判断韦小宝什么时候出千了?

我们可以这样建模$x_i$表示第$i$次投掷的骰子的种类,$y_i$表示第$i$次投掷出的点数,$\lambda$表示各个概率参数。

那么第$t$次使用第$i$种骰子投掷的概率$\delta_t(i)$等于

\begin{equation} \delta_t(i)=\max_{x_1,\dots,x_{t-1}}P(x_1,\dots,x_{t-1},x_t=i,y_1,\dots,y_t|\lambda) \end{equation}

其实$\delta_{t+1}(i)$可以由$\delta_t(i)$推倒得出:

\begin{eqnarray} \delta_{t+1}(i) &=& \max_{x_1,\dots,x_{t}}P(x_1,\dots,x_{t},x_{t+1}=i,y_1,\dots,y_{t+1}|\lambda)\\ &=& \max_j \delta_t(j)\alpha_{ji}\beta_i(y_{t+1})\end{eqnarray}

其中$\alpha_{ji}$表示从第$j$个骰子转移到第$i$个骰子的概率。

$\beta_i(y_{t+1})$表示使用第i个骰子投出点$y_{t+1}$的概率。

从而可以使用上述利用动态规划算法进行逐次递推计算。

得到的结果为:

t $y_t$ $\delta_t(A)$ $\Psi_t(A)$ $\delta_t(B)$ $\Psi_t(B)$
1 1 0.1 A 0.04 A
2 3 0.0133333 A 0.0036 B
3 4 0.00177778 A 0.000324 B
4 5 0.000237037 A 0.000106667 A
5 5 3.16049e-05 A 2.88e-05 B
6 6 4.21399e-06 A 7.776e-06 B
7 6 5.61866e-07 A 2.09952e-06 B
8 3 7.49154e-08 A 1.88957e-07 B
9 2 9.98872e-09 A 1.70061e-08 B
10 6 1.33183e-09 A 4.59165e-09 B

因为最后一步$\delta_t(B)$的值大于$\delta_t(A)$,所以一次使用B骰子的概率最大,从而一直向上回溯,得到的使用骰子的序列为:AAABBBBBBB

代码如下所示:

 #include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
using namespace std;
double initP[] = {0.6, 0.4};//骰子A,B的初始概率
double transferMatrix[][] = {{0.8, 0.2}, {0.1, 0.9}};//骰子之间的转移概率
double EmissionP[][]={{/6.0, /6.0, /6.0, /6.0, /6.0, /6.0},//骰子A的发射概率
{0.1, 0.1, 0.1, 0.1, 0.3, 0.3}};//骰子B的发射概率
double dp[][];//dp[i][j]第i步时,使用第j个骰子的最大概率
double dpS[][];//dpS[i][j]第i步时,使用第j个骰子,得到的最大概率时,使用的骰子种类, 0->A, 1->B
int ob[] = {, , , , , , , , , };//观测点数
bool diceArray[];//预测骰子使用序列
void Viterbi()
{
memset(dp,,sizeof(dp));
memset(dpS,,sizeof(dpS));
memset(diceArray,,sizeof(diceArray));
dp[][] = initP[]* EmissionP[][ob[]-];
dp[][] = initP[]* EmissionP[][ob[]-];
for( int i = ; i < ; i++ )//投掷次数
{
for( int j = ; j < ; j++ )//当前状态
{
for( int k = ; k < ; k++ )//上一个状态
{
double tempP = dp[i-][k] * transferMatrix[k][j] * EmissionP[j][ob[i]-] ;
if( dp[i][j] < tempP )
{
dp[i][j] = tempP;
dpS[i][j] = k;
}
}
}
}
int maxState = ;
if( dpS[][] < dpS[][] )
{
maxState = ;
}
for( int i = ; i >= ; i-- )
{
diceArray[i] = maxState;
maxState = dpS[i][maxState];
}
}
int main(int argc, char *argv[])
{
Viterbi();
cout<<"每步每个状态下的概率和骰子种类:"<<endl;
for( int i = ; i < ; i++ )
{
for( int j = ; j < ; j++ )
{
cout<<dp[i][j]<<" "<<dpS[i][j]<<" ";
}
cout<<endl;
}
cout<<"预测骰子种类,0->A, 1->B : "<<endl;
for( int i = ; i < ; i++ )
{
cout<<diceArray[i]<<" ";
}
cout<<endl;
}
/* result:
每步每个状态下的概率和骰子种类:
0.1 0 0.04 0
0.0133333 0 0.0036 1
0.00177778 0 0.000324 1
0.000237037 0 0.000106667 0
3.16049e-05 0 2.88e-05 1
4.21399e-06 0 7.776e-06 1
5.61866e-07 0 2.09952e-06 1
7.49154e-08 0 1.88957e-07 1
9.98872e-09 0 1.70061e-08 1
1.33183e-09 0 4.59165e-09 1
预测骰子种类,0->A, 1->B :
0 0 0 1 1 1 1 1 1 1
*/

隐马尔科夫模型及Viterbi算法的应用的更多相关文章

  1. HMM:隐马尔科夫模型-前向算法

    http://blog.csdn.net/pipisorry/article/details/50722376 目标-解决HMM的基本问题之一:已知HMM模型λ及观察序列O,如何计算P(O|λ)(计算 ...

  2. 隐马尔可夫模型及Viterbi算法

    隐马尔可夫模型(HMM,hidden Markov model)是可用于标注问题的统计学模型,描述由隐藏的马尔可夫链随机生成观测序列的过程,属于生成模型.HMM模型主要用于语音识别,自然语言处理,生物 ...

  3. HMM:隐马尔科夫模型-维特比算法

    http://blog.csdn.net/pipisorry/article/details/50731584 目标-解决HMM的基本问题之二:给定观察序列O=O1,O2,-OT以及模型λ,如何选择一 ...

  4. 隐马尔科夫模型(HMM)的概念

    定义隐马尔科夫模型可以用一个三元组(π,A,B)来定义:π 表示初始状态概率的向量A =(aij)(隐藏状态的)转移矩阵 P(Xit|Xj(t-1)) t-1时刻是j而t时刻是i的概率B =(bij) ...

  5. 隐马尔科夫模型(Hidden Markov Models)

    链接汇总 http://www.csie.ntnu.edu.tw/~u91029/HiddenMarkovModel.html 演算法笔记 http://read.pudn.com/downloads ...

  6. 隐马尔科夫模型(Hidden Markov Models) 系列之三

    转自:http://blog.csdn.net/eaglex/article/details/6418219 隐马尔科夫模型(Hidden Markov Models) 定义 隐马尔科夫模型可以用一个 ...

  7. 隐型马尔科夫模型(HMM)向前算法实例讲解(暴力求解+代码实现)---盒子模型

    先来解释一下HMM的向前算法: 前向后向算法是前向算法和后向算法的统称,这两个算法都可以用来求HMM观测序列的概率.我们先来看看前向算法是如何求解这个问题的. 前向算法本质上属于动态规划的算法,也就是 ...

  8. 隐马尔科夫模型(hidden Markov Model)

    万事开头难啊,刚开头确实不知道该怎么写才能比较有水平,这篇博客可能会比较长,隐马尔科夫模型将会从以下几个方面进行叙述:1 隐马尔科夫模型的概率计算法  2 隐马尔科夫模型的学习算法 3 隐马尔科夫模型 ...

  9. 隐马尔科夫模型python实现简单拼音输入法

    在网上看到一篇关于隐马尔科夫模型的介绍,觉得简直不能再神奇,又在网上找到大神的一篇关于如何用隐马尔可夫模型实现中文拼音输入的博客,无奈大神没给可以运行的代码,只能纯手动网上找到了结巴分词的词库,根据此 ...

随机推荐

  1. php 换行 空格分割处理

    <?php function parse_specification($specification){ $rt=array(); $lines=array_filter(preg_split(& ...

  2. js 参数的 引用与值传递

    js中arr的赋值不影响原数组,赋值和引用的区别 1.赋值 var a = 1; var b = a;   //赋的是a的复制值 b ++; alert(a);   //"1"   ...

  3. Linux服务器集群系统(三)--转

    引用地址:http://www.linuxvirtualserver.org/zh/lvs3.html LVS集群中的IP负载均衡技术 章文嵩(wensong@linux-vs.org) 2002 年 ...

  4. 【源码】基于SQLite实现CMS论坛(BBS)----附件SQLite可视化界面客户端

              使用说明:管理员账号:admin  密码:523523523   一.  账号管理(登陆注册审核) 1.账号注册 url:/BBS/Account/pregister.aspx 2 ...

  5. A+B Coming

    Problem Description Many classmates said to me that A+B is must needs.If you can’t AC this problem, ...

  6. jquery.blockUI.2.31.js 弹出层项目介绍

    {insert_scripts files='user.js'} <style type="text/css"> #float_login{border:1px sol ...

  7. Java中Integer的最大值和最小值

    从JDK1.0开始,Integer中就定义了MIN_VALUE和MAX-VALUE两个常量: /** * A constant holding the minimum value an {@code ...

  8. Oracle基础 shutdown和startup

    一.shutdown命令:SHUTDOWN有四个参数:NORMAL.TRANSACTIONAL.IMMEDIATE.ABORT.缺省不带任何参数时表示是NORMAL. SHUTDOWN NORMAL: ...

  9. 用Chrome浏览器模拟手机,android,iphone,ipad访问网站

    很多网站都通过User-Agent来判断浏览器类型,如果是3G手机,显示手机页面内容,如果是普通浏览器,显示普通网页内容.谷歌Chrome浏览 器,可以很方便地用来当3G手机模拟器.在Windows的 ...

  10. p39

    ; ========================================== ; pmtest2.asm ; 编译方法:nasm pmtest2.asm -o pmtest2.com ; ...