求期望问题小结 From ZJUTBBS
2017-03-03 15:29
218 查看
前几天一直纠结在《地下迷宫》那题中,苦苦思索无果。在一个月黑风高的夜晚,终于开窍,原来期望就是这么回事。赛后DK跟我说求期望很简单,我以为是诓我去做这个题目。我心说,您老人家看什么不简单啊,何况你还是期望控。现在觉得果然是简单的,用我的人品做担保,真的很简单。
先来看一个小例子:如图,从起点0,走到终点4。每次等概率地随机选择一条路走,(比如当前在0点,下一步分别有1/3的可能走到1,2,3点;对于1 点,下一步各有1/3的可能走到1点,0点,2点),求平均需要用几步走到终点4,也就是求走到4点所花步数的期望。
分析:
要从0走到4,从第一步的角度来看,无非是三种途径:
①先走到1,然后经过若干过程从1走到4;
②先走到2,然后经过若干过程从2走到4;
③先走到3,然后经过若干过程从3走到4。
假如我们已经知道了从1、2、3走到4所要花的平均步数分别是E(1)、E(2)、E(3),那么从0走到4的步数,有三种可能:E(1)+1、
E(2)+1、E(3)+1,而且这三种是等概率的。那么从0走到4的平均步数就是(E(1)+1+E(2)+1+E(3)+1)/3。现在我们并不知道 E(1)、E(2)、E(3)的值,得到的只是一个方程E(0)=(E(1)+E(2)+E(3))/3+1
同样的,对于点2,我们可以列出方程E(2)=(E(0)+E(1)+E(3)+E(4))/4+1。
有人说了,我靠,E(4)是什么东东?
E(4)当然就是从4点走到4点所花的平均步数,显然有E(4)=0。
联立方程组
E(0)=(E(1)+E(2)+E(3))/3+1
E(1)=(E(0)+E(1)+E(2))/3+1
E(2)=(E(0)+E(1)+E(3)+E(4))/4+1
E(3)=(E(0)+E(2)+E(4))/3+1
E(4)=0
图是我随手画的,求出来的解不整,保留两位小数如下:
E[0]=8.38
E[1]=9.14
E[2]=6.90
E[3]=6.10
E[4]=0.00
现在只要会编程解方程组就大功告成了。线性代数里讲过,可以用矩阵来表示线性方程组,用高斯消元法对矩阵进行处理,即可求解。有的小朋友没学线性代数,有 的和我一样学完后早忘到脚后跟去了。我是从网上搜了个高斯消元的代码来研究学习的。要不老衲买一赠一,顺道把高斯消元也解释一下吧。
-----------------------促销大派送之高斯消元---------------------------
上述方程组整理可得(为了减少精度损失,在某些式子上乘个常数,使系数整一点):
3*E(0) -E(1) -E(2) -E(3)+0*E(4)=3
-E(0)+2*E(1) -E(2)+0*E(3)+0*E(4)=3
-E(0) -E(1)+4*E(2) -E(3) -E(4)=4
-E(0)-0*E(1) -E(2)-3*E(3) -E(4)=3
0*E(0) +0*E(1) +0*E(2)+0*E(3) +E(4)=0
我们用一个5*5的二维数组a来描述等号左边各项的系数,用数组b来表示等号右边的常数项。直接用一个5*6的矩阵来表示当然也是可以的。数组的数据类型为double
a b
[0] 3 -1 -1 -1 0 | 3
[1] -1 2 -1 0
0 |3
[2] -1 -1 4 -1 -1| 4
[3] -1 0 -1 3 -1 | 3
[4] 0 0 0
0 1 | 0
注意,在我的叙述中,行号列号都是从0开始编的。
由方程组的性质,我们知道,可以给某一行乘上一个非零常数,可以把某一行乘一个非零常数加到另一行上去,可以任意调换两行的位置。这些操作都不影响方程组 的解,叫做行初等变换。我们利用行初等变换来处理矩阵。首先,我想让左边只留一个E(0),其他的E(0)系数都消掉。我们选择保留第0行,在第1、2、
3行上都加上第0行的1/3,矩阵变成了这样(只显示两位小数,下同):
3.00 -1.00
-1.00 -1.00 0.00|
3.00
0.00 1.67
-1.33 -0.33 0.00|
4.00
0.00 -1.33
3.67 -1.33 -1.00|
5.00
0.00 -0.33
-1.33 2.67 -1.00|
4.00
0.00 0.00
0.00 0.00 1.00|
0.00
第0行就固定不动了,接着我让下面四行只留一个E(1),其他的消掉。方法是在第2行上加上第1行的4/5,在第3行上加上第1行的1/5。处理后:
3.00 -1.00
-1.00 -1.00 0.00|
3.00
0.00 1.67
-1.33 -0.33 0.00|
4.00
0.00 0.00
2.60 -1.60 -1.00|
8.20
0.00 0.00
-1.60 2.60 -1.00|
4.80
0.00 0.00
0.00 0.00 1.00|
0.00
从上面的步骤可以看出,在消元的时候,我们需要从下面剩下的行中选择一个需要保留的行,这里称作主元行。选择的标准是什么?比如上一步,我们完全可以把第 1行加上第3行的5倍,把第2行加上第3行的-4倍。我看的那篇文章上说,选择该列中绝对值最大的那一行作为主元行,这样可以减少精度损失。好吧,我们相
信这个说法。假设a[1][1]这个位置不是1.67,而是0.67,那么这一列中绝对值最大的系数就是a[2][1]的-1.33(注意,第0行是不参
与比较的,它已经固定下来了)。那我们就交换第1、2行,把-1.33这一行提到上面,然后再执行消元操作,把这一列的下面都消成0。
如果处理到某一列的时候,发现这一列剩下的系数竟然全是0了,比如这样的:
1 2 3 4| 5
0 6 7 8| 9
0 0 0 1| 2
0 0 0 2| 4
第2列剩下的全是0了,找不到主元行了,这说明该矩阵的秩小于元数,方程组解不出唯一解来。通俗点说,就是这些方程里有水货,表面上看是4个方程,可仔细一瞧,第2行和第3行本质上是一样的,当然解不出。
好了,回到我们刚才的例子,通过一番处理之后,矩阵的左下角全变成0了。这称为行阶梯式。
3.00 -1.00
-1.00 -1.00 0.00|
3.00
0.00 1.67
-1.33 -0.33 0.00|
4.00
0.00 0.00
2.60 -1.60 -1.00|
8.20
0.00 0.00
0.00 1.62 -1.62|
9.85
0.00 0.00
0.00 0.00 1.00|
0.00
根据最后一行,可以确定E(4)的值,我们把它存到x[4]里。把E(4)代入到3式,可以解出E(3);把E(3)、E(4)代入2式,解出E(2)……
代码实现如下:
------------------------赠品End------------------------
高斯消元解方程组的复杂度是O(N^3),回到地下迷宫这题,对所有的连通点联立方程组。连通点的个数不超过100,代码见这里
http://bbs.zjut.com/viewthread.php?tid=1167909&page=1#pid6158985(链接已经失效)
扩展1:POJ 3682 King Arthur's Birthday Celebration
http://acm.pku.edu.cn/JudgeOnline/problem?id=3682
题目大意是说扔硬币,有p的概率是正面,1-p的概率是反面。每天扔一次,直到累计扔出k个正面为止。在扔硬币期间,第一天花1千块钱,第二天花3千,第三天花5千……
求平均扔几次会停止,平均会花多少钱。
以k=3,p=0.5为例,按已扔出几个正面来区分,共有4种状态。各状态之间按如下的概率转移。
先来看一个小例子:如图,从起点0,走到终点4。每次等概率地随机选择一条路走,(比如当前在0点,下一步分别有1/3的可能走到1,2,3点;对于1 点,下一步各有1/3的可能走到1点,0点,2点),求平均需要用几步走到终点4,也就是求走到4点所花步数的期望。
分析:
要从0走到4,从第一步的角度来看,无非是三种途径:
①先走到1,然后经过若干过程从1走到4;
②先走到2,然后经过若干过程从2走到4;
③先走到3,然后经过若干过程从3走到4。
假如我们已经知道了从1、2、3走到4所要花的平均步数分别是E(1)、E(2)、E(3),那么从0走到4的步数,有三种可能:E(1)+1、
E(2)+1、E(3)+1,而且这三种是等概率的。那么从0走到4的平均步数就是(E(1)+1+E(2)+1+E(3)+1)/3。现在我们并不知道 E(1)、E(2)、E(3)的值,得到的只是一个方程E(0)=(E(1)+E(2)+E(3))/3+1
同样的,对于点2,我们可以列出方程E(2)=(E(0)+E(1)+E(3)+E(4))/4+1。
有人说了,我靠,E(4)是什么东东?
E(4)当然就是从4点走到4点所花的平均步数,显然有E(4)=0。
联立方程组
E(0)=(E(1)+E(2)+E(3))/3+1
E(1)=(E(0)+E(1)+E(2))/3+1
E(2)=(E(0)+E(1)+E(3)+E(4))/4+1
E(3)=(E(0)+E(2)+E(4))/3+1
E(4)=0
图是我随手画的,求出来的解不整,保留两位小数如下:
E[0]=8.38
E[1]=9.14
E[2]=6.90
E[3]=6.10
E[4]=0.00
现在只要会编程解方程组就大功告成了。线性代数里讲过,可以用矩阵来表示线性方程组,用高斯消元法对矩阵进行处理,即可求解。有的小朋友没学线性代数,有 的和我一样学完后早忘到脚后跟去了。我是从网上搜了个高斯消元的代码来研究学习的。要不老衲买一赠一,顺道把高斯消元也解释一下吧。
-----------------------促销大派送之高斯消元---------------------------
上述方程组整理可得(为了减少精度损失,在某些式子上乘个常数,使系数整一点):
3*E(0) -E(1) -E(2) -E(3)+0*E(4)=3
-E(0)+2*E(1) -E(2)+0*E(3)+0*E(4)=3
-E(0) -E(1)+4*E(2) -E(3) -E(4)=4
-E(0)-0*E(1) -E(2)-3*E(3) -E(4)=3
0*E(0) +0*E(1) +0*E(2)+0*E(3) +E(4)=0
我们用一个5*5的二维数组a来描述等号左边各项的系数,用数组b来表示等号右边的常数项。直接用一个5*6的矩阵来表示当然也是可以的。数组的数据类型为double
a b
[0] 3 -1 -1 -1 0 | 3
[1] -1 2 -1 0
0 |3
[2] -1 -1 4 -1 -1| 4
[3] -1 0 -1 3 -1 | 3
[4] 0 0 0
0 1 | 0
注意,在我的叙述中,行号列号都是从0开始编的。
由方程组的性质,我们知道,可以给某一行乘上一个非零常数,可以把某一行乘一个非零常数加到另一行上去,可以任意调换两行的位置。这些操作都不影响方程组 的解,叫做行初等变换。我们利用行初等变换来处理矩阵。首先,我想让左边只留一个E(0),其他的E(0)系数都消掉。我们选择保留第0行,在第1、2、
3行上都加上第0行的1/3,矩阵变成了这样(只显示两位小数,下同):
3.00 -1.00
-1.00 -1.00 0.00|
3.00
0.00 1.67
-1.33 -0.33 0.00|
4.00
0.00 -1.33
3.67 -1.33 -1.00|
5.00
0.00 -0.33
-1.33 2.67 -1.00|
4.00
0.00 0.00
0.00 0.00 1.00|
0.00
第0行就固定不动了,接着我让下面四行只留一个E(1),其他的消掉。方法是在第2行上加上第1行的4/5,在第3行上加上第1行的1/5。处理后:
3.00 -1.00
-1.00 -1.00 0.00|
3.00
0.00 1.67
-1.33 -0.33 0.00|
4.00
0.00 0.00
2.60 -1.60 -1.00|
8.20
0.00 0.00
-1.60 2.60 -1.00|
4.80
0.00 0.00
0.00 0.00 1.00|
0.00
从上面的步骤可以看出,在消元的时候,我们需要从下面剩下的行中选择一个需要保留的行,这里称作主元行。选择的标准是什么?比如上一步,我们完全可以把第 1行加上第3行的5倍,把第2行加上第3行的-4倍。我看的那篇文章上说,选择该列中绝对值最大的那一行作为主元行,这样可以减少精度损失。好吧,我们相
信这个说法。假设a[1][1]这个位置不是1.67,而是0.67,那么这一列中绝对值最大的系数就是a[2][1]的-1.33(注意,第0行是不参
与比较的,它已经固定下来了)。那我们就交换第1、2行,把-1.33这一行提到上面,然后再执行消元操作,把这一列的下面都消成0。
如果处理到某一列的时候,发现这一列剩下的系数竟然全是0了,比如这样的:
1 2 3 4| 5
0 6 7 8| 9
0 0 0 1| 2
0 0 0 2| 4
第2列剩下的全是0了,找不到主元行了,这说明该矩阵的秩小于元数,方程组解不出唯一解来。通俗点说,就是这些方程里有水货,表面上看是4个方程,可仔细一瞧,第2行和第3行本质上是一样的,当然解不出。
好了,回到我们刚才的例子,通过一番处理之后,矩阵的左下角全变成0了。这称为行阶梯式。
3.00 -1.00
-1.00 -1.00 0.00|
3.00
0.00 1.67
-1.33 -0.33 0.00|
4.00
0.00 0.00
2.60 -1.60 -1.00|
8.20
0.00 0.00
0.00 1.62 -1.62|
9.85
0.00 0.00
0.00 0.00 1.00|
0.00
根据最后一行,可以确定E(4)的值,我们把它存到x[4]里。把E(4)代入到3式,可以解出E(3);把E(3)、E(4)代入2式,解出E(2)……
代码实现如下:
#define EPS 1e-10 int N; #define MAX 100 double a[MAX][MAX],b[MAX],x[MAX]; bool flag; double ab(double x) { return (x>=0)?x:-x; } void Gauss() { flag=1; double maxi,d; int index,i,j,k; for(k=0;k<N;k++) { maxi=0; for(i=k;i<N;i++)//找该列绝对值最大的行 { if(ab(a[i ][k])>maxi) { index=i; maxi=ab(a[i ][k]); } } if(maxi<EPS)//如果剩下的全是0,失败返回 { flag=0; return; } if(index!=k)//把主元行交换到上面来 { swap(b[index],b[k]); for(j=k;j<N;j++) swap(a[index][j],a[k][j]); } for(i=k+1;i<N;i++)//把非主元行的系数消掉 { d=a[i ][k]/a[k][k]; b[i ]-=b[k]*d; a[i ][k]=0; for(j=k+1;j<N;j++) a[i ][j]-=a[k][j]*d; } } //至此,已经得到一个行阶梯式 for(i=N-1;i>=0;i--)//从底向上依次代入求解 { for(j=i+1;j<N;j++) b[i ]-=a[i ][j]*x[j]; x[i ]=b[i ]/a[i ][i ]; } }
------------------------赠品End------------------------
高斯消元解方程组的复杂度是O(N^3),回到地下迷宫这题,对所有的连通点联立方程组。连通点的个数不超过100,代码见这里
http://bbs.zjut.com/viewthread.php?tid=1167909&page=1#pid6158985(链接已经失效)
扩展1:POJ 3682 King Arthur's Birthday Celebration
http://acm.pku.edu.cn/JudgeOnline/problem?id=3682
题目大意是说扔硬币,有p的概率是正面,1-p的概率是反面。每天扔一次,直到累计扔出k个正面为止。在扔硬币期间,第一天花1千块钱,第二天花3千,第三天花5千……
求平均扔几次会停止,平均会花多少钱。
以k=3,p=0.5为例,按已扔出几个正面来区分,共有4种状态。各状态之间按如下的概率转移。
相关文章推荐
- web项目之BBS发布至新浪云配置修改以及sql语句修改问题小结
- bbs论坛问题小结1
- ZJUT 1317 掷飞盘 (高斯解期望问题)
- web项目--BBS之从数据库查询动态生成版块信息问题分析和小结
- 关于使用ODBC+VC操作DBF文件问题小结
- 孤独剑客的推荐安全站点 (from http://bbs.isbase.net)
- 谁有能让窗体自动适应显示器分辨率的控件? From: www.delphibbs.com
- tomcat 5.X 的mysql DBCP配置指南及相关问题小结
- “问题其实就是你的期望和你的体验之间的差别”《Are Your Lights》--- 你的灯亮着吗?读后感(1)
- matlab的combuilder系列-matlab下做com组件 zzfrom SMTH bbs
- ireport的中文问题小结
- 酒桌上应对(from:http://www.haozai.com/bbs/dispbbs.asp?boardID=6&ID=106&page=1)
- JSP中文乱码问题解决方法小结
- 复变函数--from BBS 水木清华站
- a job stcik from smth bbs today
- 为FC3安装vmware tools问题的完美解决方案--come from vmware.cn' jorin
- Eclipse3.0+lomboz3.01+tomcat5.027安装调式问题小结-zz
- 最新免费空间排行榜 from bbs.crsky.com
- FedoraCore2正式版使用问题解决集中(from:linuxsir
- Eclipse3.0+lomboz3.01+tomcat5.027安装调式问题小结