作者: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. MR-为什么MR类的变量喜欢定义在方法外面?

    写了一些MR后发现不管是别人写的还是官方给的,比如map方法,变量都是定义在方法外面. 因为之前都是照猫画虎的写的,所以自己也一直这么写,可是为什么呢? 我试了试定义在方法里面,程序照样跑,试了几个程 ...

  2. 在使用ICSharpCode.SharpZipLib进行目录压缩后,再解压缩是提示这个错误Size mismatch: 4294967295;126976 70202;126976

    在压缩代码中加入entry.CompressionMethod = CompressionMethod.Stored

  3. 1.4.2 solr字段类型--(1.4.2.3)使用货币和汇率

    1.4.2 solr字段类型 (1.4.2.1) 字段类型定义和字段类型属性. (1.4.2.2) solr附带的字段类型 (1.4.2.3) 使用货币和汇率 (1.4.2.4) 使用Dates(日期 ...

  4. 【Shell脚本学习16】Shell if else语句

    if 语句通过关系运算符判断表达式的真假来决定执行哪个分支.Shell 有三种 if ... else 语句: if ... fi 语句: if ... else ... fi 语句: if ... ...

  5. iOS中通知中心NSNotificationCenter应用总结

    通知中心(NSNotificationCenter)实际是在程序内部提供了一种广播机制.把接收到的消息,根据内部的消息转发表,将消息转发给需要的对象.这句话其实已经很明显的告诉我们要如何使用通知了.第 ...

  6. Oracle基础 数据库备份和恢复

    一.为什么需要数据备份 造成数据丢失的主要原因: 1.介质故障. 2.用户的错误操作. 3.服务器的彻底崩溃. 4.计算机病毒. 5.不可预料的因素. Oracle中故障类型分为以下4种. 1.语句故 ...

  7. 树形菜单复选框级联选择HTML

    模块标题 标识符 类别 链接 排序 系统管理   组   1 用户权限设定 Sys_UserModelConfigList 模块 Sys_UserModelConfigList.aspx 1 角色管理 ...

  8. angularJs中上传图片/文件功能:ng-file-upload

    原文技术交流:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/angularjs-ng-file-upload/ 在做网站的过程中难 ...

  9. hdu 4409 LCA

    思路:就是个比较裸的LCA了,不过要注意的是,如果a和b的公共祖先是a,那么答案就是farther[a]. #include<cstring> #include<cmath> ...

  10. DevExpress使用之ChartControl控件绘制图表(多坐标折线图、柱状图、饼状图)

    最近因为公司项目需要用到WinForm的DecExpress控件,在这里把一些使用方法总结一下. DevExpress中有一个专门用来绘制图表的插件ChartControl,可以绘制折线图.饼状图.柱 ...