隐马尔可夫模型(HMM) HDU4865 Peter's Hobby

来源:互联网 发布:怎么用淘宝助理 编辑:程序博客网 时间:2024/05/20 08:00

题目链接 

隐马尔可夫模型(Hidden Markov Model,HMM)的裸题目,在HMM中,状态序列不可知,可知的是观测序列,状态的概率转移矩阵以及观测值在不同状态下的概率分布是可知的,HMM中常见的问题是估计概率和参数,主有有三个:

1.已知模型参数,计算某一特定输出序列的概率.通常使用forward算法解决.

2.已知模型参数,寻找最可能的能产生某一特定输出序列的隐含状态的序列.通常使用Viterbi算法解决.

3.已知输出序列,寻找最可能的状态转移以及输出概率.通常使用Baum-Welch算法以及Reversed Viterbi算法解决.

问题1,2可用动态规划解决,问题3??

本题是问题2的裸题

#include <algorithm>#include <cstdio>#include <cstring>#include <iostream>#include <map>#include <set>#include <string>#include <cmath>#include <vector>#include <queue>using namespace std;#define  N    111#define  LL   long long#define  mod  1000000007ll#define  inf  0XFFFFFFF#define  pii  pair<int, int>#define  mp   make_pair#define  eps  1e-3#define  euC    0.57721566490153286060651209;double a[3][3] = {    {0.5, 0.375, 0.125},    {0.25, 0.125, 0.625},    {0.25, 0.375, 0.375}};double b[3][4] = {    {0.6, 0.2, 0.15, 0.05},    {0.25, 0.3, 0.2, 0.25},    {0.05, 0.1, 0.35, 0.5}};int o[N];int n;double pai[3] = {0.63, 0.17, 0.2};double dp[N][N];int path[N][N];int ans[N];int Main() {    //freopen("cf.txt","r", stdin);    int T; cin >> T;    for (int tt = 0; tt < T; tt++) {        cin >> n;        for (int i = 0; i < n; i++) {            string s; cin >> s;            if (s == "Dry") o[i] = 0;            else if (s == "Dryish") o[i] = 1;            else if (s == "Damp") o[i] = 2;            else if (s == "Soggy") o[i] = 3;        }        for (int i = 0; i < 3; i++) {            dp[0][i] = log(pai[i]) + log(b[i][o[0]]);        }        for (int i = 1; i < n; i++) {            for (int j = 0; j < 3; j++) {                dp[i][j] = -1e200;                path[i][j] = -1;                for (int k = 0; k < 3; k++) {                    if (dp[i][j] < dp[i-1][k] + log(a[k][j]) + log(b[j][o[i]])) {                        dp[i][j] = dp[i-1][k] + log(a[k][j]) + log(b[j][o[i]]);                        path[i][j] = k;                    }                }            }        }        cout << "Case #" << tt + 1 << ":" << endl;        ans[n-1] = 0;        for (int i = 0; i < 3; i++)            if (dp[n-1][i] > dp[n-1][ans[n-1]])                ans[n-1] = i;        for (int i = n-2; i >= 0; i--) {            ans[i] = path[i+1][ans[i+1]];        }        for (int i = 0; i < n; i++) {            if (ans[i] == 0) cout << "Sunny" << endl;            else if (ans[i] == 1) cout << "Cloudy" << endl;            else cout << "Rainy" << endl;        }    }    return 0;}int main() {    return Main();}




0 0