作者: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. 代码片段--Makefile之大型工程项目子目录Makefile的一种通用写法

    转载:http://blog.csdn.net/mo_hui123456/article/details/8929615 管理Linux环境下的C/C++大型项目,如果有一个智能的Build Syst ...

  2. Linux编程之《看门狗进程》

    Intro 当我们编写服务器代码时,为了让自己的服务器在意外崩溃时能够及时的重启,软件看门狗就显示出它的作用了,该看门狗进程是通过fork一个子进程(业务进程),父进程一旦捕获到了子进程的结束信号就重 ...

  3. iOS企业级开发者计划的申请流程

    第一步:访问苹果企业版iDP网址:https://developer.apple.com/programs/ios/enterprise/点击Apply Now按钮,开始申请流程. 第二步:点击App ...

  4. 安装PIL库时提示python未注册错误(自定义python安装路径)

    import sys from _winreg import * # tweak as necessary version = sys.version[:3] installpath = sys.pr ...

  5. ImageSource使用心得(转)

    很多时候,我们会使用图片来装饰UI,比如作为控件背景等. 而这些图片可以分为两种形式,即存在于本地文件系统中的图片和存在于内存中的图片 对于这两种形式的图片,在WPF中,使用方法不同,下面主要说明针对 ...

  6. [Java] 模拟HTTP的Get和Post请求

    在之前,写了篇Java模拟HTTP的Get和Post请求的文章,这篇文章起源与和一个朋友砍飞信诈骗网站的问题,于是动用了Apache的comments-net包,也实现了get和post的http请求 ...

  7. 基于MFC的Opengl实现动画

    对于了解MFC程序设计的来说,就太简单了.像我这种的,还是有必要记下来. OnCreate设置定时:SetTimer(1, 10, NULL);//设置#1定时器 key point void COp ...

  8. WebStrom9 体验nodejs

    之前就有体验过 WebStrom8.0.3 版本,确实不错. 最喜欢的是集成了Terminal 很方便的使用NPM,今天装上发现 Terminal 死活打不上字.什么原因! WebStrom9 在wi ...

  9. 关于automatic_Panoramic_Image_Stitching_using_Invariant_features 的阅读笔记(2)

    接上一篇: http://www.cnblogs.com/letben/p/5446074.html#3538201 捆绑调整 (好开心有同学一起来看看这些问题,要不然就是我自己的话,我应该也不会看的 ...

  10. python 基础——常用日志装饰器

    from functools import wraps class logit(): def __init__(self, logfile='out.log'): self.log = logfile ...