先从阿里机器学习算法岗网络笔试题说起:甲乙两人进行一个猜硬币的游戏。每个人有一个目标序列,由裁判来抛硬币。谁先得到裁判抛出的一串连续结果,谁赢。

甲的目标序列是正正正,乙的目标序列是反正正。那么如果裁判抛出了正正反正反正正....抛到第7个结果时乙胜,因为最后三个序列是“反正正”,而前面不存在甲的“正正正”序列。

问:甲的目标序列是????,乙的目标序列是????,求两人各自获胜的概率。

先说例子,正正正,反正正的概率。显然是1/8和7/8.  甲获胜的情况只有一种,就是三个连续的正,P = 1/8。为什么呢?因为,一旦裁判抛出一个“反”,结果就已经确定是乙胜了。所以甲要想获胜,只能从开头就是连着三个正。

那么对于一般题怎么做呢?

AC自动机 + 高斯消元。

你可以理解成 有限状态自动机+解方程。

(不好意思  这个图有误,所有曲线指的不应该是根节点,而应该是根节点读入"反"后的右节点)

根节点是开始,每抛出一个硬币走一条边。谁先走到最底下的点就胜。

到底部的获胜概率就是从开始局面到底部的期望次数。(到所有终点的期望和是1,等价于所有人的获胜概率和是1)

这么转换后就能做了。每个结点的期望 = 它前驱结点的期望 的 加权平均值。

如果只有一条边出去,那么它的下一个结点的期望显然就等于它的期望。

自环也算进去,加权算。

那么就能对每个结点列方程,n元一次方程。常数项在哪里?

在根节点前虚拟一个结点,指向根结点。虚拟结点的期望是1。

然后就能高斯消元做了!

以上的过程其实是一个 马尔科夫 过程。

我们解决了自动机到终点的概率(获胜概率,也就是到终点的期望次数),我们类似可以解决自动机走到终点的期望步数。也就是裁判期望抛多少回硬币游戏能够结束?

同样是列方程。

xi表示到i结点需要走的期望步数, xi = 1+∑ (pj*xj), (xj 是xi 的前驱结点, pj是xj结点走到到xi结点的概率)???

xi表示从i结点走到终点的期望步数, xi = 1+∑ (pj*xj), (xj 是xi 的后继结点, pj是xj结点走到到xi结点的概率)

以上。

扩展

如果你和一个人玩游戏,是否存在一种情况,无论对方的序列是什么序列,你都能够构造出一个 等长 的序列,使你的获胜概率比对方大?

答案是:当序列长度 > 2时,你总能使自己获胜概率更大。

详见 matrix67

现场赛的题是投骰子,谁先投出自己的序列谁胜。求各自获胜概率。

正解:ac自动机+高斯消元。

有一个做n遍消元的解法:对每个人的目标点消元。具体就是设xi为i结点到目标点的概率,dp算出根结点的值就是从根节点到目标点的概率。做n次即可。

还有一种有误差的解法。矩阵快速幂。矩阵的n次幂表示从根节点走n步到各个点的概率。n足够大时,就能近似表示出到各个点的概率。可惜,精度还是不够,误差比较大。。。。

还是要贴一下AC代码的。

 #include <bits/stdc++.h>
#define gg puts("gg");
using namespace std;
const double eps = 1e-;
const int N = ;
int id(int c){
return c-;
}
struct Tire{
int nex[N][], fail[N], end[N];
int root, L;
int newnode(){
memset(nex[L], -, sizeof(nex[L]));
end[L] = ;
return L++;
}
void init(){
L = ;
root = newnode();
}
void insert(int* s, int l, int k){
int now = root;
for(int i = ; i < l; i++){
int p = id(s[i]);
if(nex[now][p] == -)
nex[now][p] = newnode();
now = nex[now][p];
}
end[now] = k;
}
void build(){
queue<int> Q;
fail[root] = root;
for(int i = ; i < ; i++){
int& u = nex[root][i];
if(u == -)
u = root;
else{
fail[u] = root;
Q.push(u);
}
}
while(!Q.empty()){
int now = Q.front();
Q.pop();
for(int i = ; i < ; i++){
int& u = nex[now][i];
if(u == -)
u = nex[ fail[now] ][i];
else{
fail[u] = nex[ fail[now] ][i];
end[u] |= end[ fail[u] ];
//last[u] = end[ fail[u] ]? fail[u] : last[ fail[u] ];
Q.push(u);
}
}
}
}
};
Tire ac; double a[][], x[], ans[];
int equ, var;
int Gauss(){
int i,j,k,col,max_r;
for(k = , col = ; k < equ&&col < var; k++, col++){
max_r = k;
for(i = k+; i < equ; i++)
if(fabs(a[i][col]) > fabs(a[max_r][col]))
max_r = i;
if(fabs(a[max_r][col]) < eps) return ;
if(k != max_r){
for(j = col; j < var; j++)
swap(a[k][j], a[max_r][j]);
swap(x[k], x[max_r]);
}
x[k] /= a[k][col];
for(j = col+; j < var; j++) a[k][j] /= a[k][col];
a[k][col] = ;
for(i = ; i < equ; i++)
if(i != k){
x[i] -= x[k]*a[i][k];
for(j = col+; j < var; j++) a[i][j] -= a[k][j]*a[i][col];
a[i][col] = ;
}
}
return ;
} int s[];
int main(){
int n, l, t, ca = ; scanf("%d", &t);
while(t--){
ac.init();
scanf("%d%d", &n, &l);
for(int i = ; i <= n; i++){
for(int j = ; j < l; j++)
scanf("%d", s+j);
ac.insert(s, l, i);
}
ac.build(); memset(a, , sizeof(a));
memset(x, , sizeof(x));
equ = ac.L, var = ac.L;
for(int i = ; i < ac.L; i++)
a[i][i] = -;
x[] = -;
for(int i = ; i < ac.L; i++){
if(!ac.end[i])
for(int j = ; j < ; j++){
int to = ac.nex[i][j];
a[to][i] += 1.0/;
}
} Gauss(); for(int i = ; i < ac.L; i++)
if(ac.end[i]) ans[ ac.end[i] ] = x[i];
for(int i = ; i <= n; i++)
printf("%.6f%c", ans[i], " \n"[i == n]);
}
return ;
}

【HDU5955】Guessing the Dice Roll/马尔科夫的更多相关文章

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

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

  2. 从随机过程到马尔科夫链蒙特卡洛方法(MCMC)

    从随机过程到马尔科夫链蒙特卡洛方法 1. Introduction 第一次接触到 Markov Chain Monte Carlo (MCMC) 是在 theano 的 deep learning t ...

  3. HMM基本原理及其实现(隐马尔科夫模型)

    HMM(隐马尔科夫模型)基本原理及其实现 HMM基本原理 Markov链:如果一个过程的“将来”仅依赖“现在”而不依赖“过去”,则此过程具有马尔可夫性,或称此过程为马尔可夫过程.马尔可夫链是时间和状态 ...

  4. 蒙特卡洛马尔科夫链(MCMC)

    蒙特卡洛马尔科夫链(MCMC) 标签: 机器学习重要性采样MCMC蒙特卡洛 2016-12-30 20:34 3299人阅读 评论(0) 收藏 举报  分类: 数据挖掘与机器学习(41)  版权声明: ...

  5. Atitit 马尔可夫过程(Markov process) hmm隐马尔科夫。 马尔可夫链,的原理attilax总结

    Atitit 马尔可夫过程(Markov process) hmm隐马尔科夫. 马尔可夫链,的原理attilax总结 1. 马尔可夫过程1 1.1. 马尔科夫的应用 生成一篇"看起来像文章的 ...

  6. 机器学习&数据挖掘笔记_19(PGM练习三:马尔科夫网络在OCR上的简单应用)

    前言: 接着coursera课程:Probabilistic Graphical Models上的实验3,本次实验是利用马尔科夫网络(CRF模型)来完成单词的OCR识别,每个单词由多个字母组合,每个字 ...

  7. PRML读书会第八章 Graphical Models(贝叶斯网络,马尔科夫随机场)

    主讲人 网神 (新浪微博: @豆角茄子麻酱凉面) 网神(66707180) 18:52:10 今天的内容主要是: 1.贝叶斯网络和马尔科夫随机场的概念,联合概率分解,条件独立表示:2.图的概率推断in ...

  8. 基于隐马尔科夫模型(HMM)的地图匹配(Map-Matching)算法

    文章目录 1. 1. 摘要 2. 2. Map-Matching(MM)问题 3. 3. 隐马尔科夫模型(HMM) 3.1. 3.1. HMM简述 3.2. 3.2. 基于HMM的Map-Matchi ...

  9. 隐马尔科夫模型HMM学习最佳范例

    谷歌路过这个专门介绍HMM及其相关算法的主页:http://rrurl.cn/vAgKhh 里面图文并茂动感十足,写得通俗易懂,可以说是介绍HMM很好的范例了.一个名为52nlp的博主(google ...

随机推荐

  1. Why MySQL could be slow with large tables ?

    https://www.percona.com/blog/2006/06/09/why-mysql-could-be-slow-with-large-tables/

  2. win8.1解决鼠标右键反应慢的问题

    进入Win8注册表之后,我们依次展开: 位置:HKEY_CLASSES_ROOT\Directory\background\shellex\ContextMenuHandlers 之后,除了面的“Ne ...

  3. spring记录

    context:property-placeholder 是将properties加载到Spring上下文中,接下来在定义bean的时候就能用${xx.xx}来访问了. util:properties ...

  4. Windows上搭建Kafka运行环境

    完整解决方案请参考: Setting Up and Running Apache Kafka on Windows OS   在环境搭建过程中遇到两个问题,在这里先列出来,以方便查询: 1. \Jav ...

  5. Asp.net导出Excel乱码的解决方法

    通过跟踪Asp.net服务器代码,没有乱码,然而导出Excel到浏览器后,打开时出现乱码. 解决方法是添加编码格式的前缀字节码:Response.BinaryWrite(System.Text.Enc ...

  6. UE4 减少APK包的大小

    本文依据官方文档 Reducing APK Package Size整理而来,不过我会陆续添加自己减少包大小的心得. ETC1 纹理 当使用ETC1打Android包时,注意ETC1是不会压缩带Alp ...

  7. 如何学习Python

    [整理]如何学习Python + 如何有效利用Python有关的网络资源 + 如何利用Python自带手册(Python Manual) http://www.crifan.com/howto_lea ...

  8. ExtJs Grid 删除,编辑,查看详细等超链接处理

    在网上查了好多资料,关于ExtJs处理操作栏的“删除”.“编辑”.“查看详细”的处理,原来项目都是这么处理: 操作栏:{ text:'操作', xtype:'actioncolumn', items ...

  9. Android系统下,用adb实现自动获取应用性能数据

    [自动化测试模式] 支持以adb shell命令的形式启动和运行.需要注意的是,office系列软件可能会更改命令中的字符,导致命令不可用!请手工输入命令,或从附带的command.txt文本中复制. ...

  10. SVN服务端启动解决方案(2013-12-10 记)

     解决每一次开机都得用DOS启动SVN服务,而DOS窗口又无法关闭的情况 1.安装Setup-Subversion-1.8.5.msi搭建好SVN服务端(下载地址:http://subversion. ...