常见概率题

从n个数中生成m个不重复的随机数

import random
for i in range(n):
	x = random.randint(n-i)
	if x < m:
		print(i)
		m -= 1

由这个for循环循环n次,且在满足条件时才输出i,可知,输出m个不同值的要求已满足,因为每次输出的都是i值,而i值每次都是不一样的,m–保证了程序在输出了m个值后就停止循环。
在i=0时,randint()的取值范围为0到n-1,共n个数,此时要输出0只需要x小于m,故i=0被输出的概率为m/n;
在i=1时,randint()的取值范围为0到n-2,共n-1个数,若i=0没有被输出,则m–未被执行,此时i=1被输出的概率为m/(n-1),若i=0已经被输出了,则m变为m-1,此时i=1被输出的概率为(m-1)/(n-1);由概率论的知识,可知此时i=1被输出的概率为
P=(1-m/n)(m/(n-1))+m/n((m-1)/(n-1))=m/n;以此类推,可知每个数被输出的概率都为m/n

上题中如果n的大小不确定(可以认为是⼀个数据流),如何做?(蓄水池抽样算法)

int[] reservoir = new int[m];

// init
for (int i = 0; i < reservoir.length; i++)
{
   
    reservoir[i] = dataStream[i];
}

for (int i = m; i < dataStream.length; i++)
{
   
    // 随机获得一个[0, i]内的随机整数
    int d = rand.nextInt(i + 1);
    // 如果随机整数落在[0, m-1]范围内,则替换蓄水池中的元素
    if (d < m)
    {
   
        reservoir[d] = dataStream[i];
    }
}
  1. 整数数组的前m个直接存下来。
  2. 用一个计数器保存当前正在处理的请求是第几个,比如n
  3. 对于从m+1开始的新请求,以m/i的概率选择保存,并同从已保存的m个请求中随机选出的一个进行交换。

首先前m个数字是必须拿的。问题是当第i(i>m)个数字来的时候,究竟是要丢弃这个数,还是保留这个数?如果要保留这个数的话,则必须得丢弃手中已有的m个数,那是怎么确定丢弃哪个呢?
下面是就具体的做法。第i个数到来的时候,以m/i的概率决定是否要选择这个数字。如果选择了这个数字,则随机地替换掉手上m个数字中的一个。
如果前i-1个数字的时候保证了每个数字被选取的概率相等,则这样做之后可以保证每个数字被选取的概率也相等,为m/i。

  1. 第i个数选择的概率是m/i,因为算法就是这样决定的。
  2. 考虑前i-1个数字中的任意一个,它在第i个数之前被选择的概率是m/(i-1)。在第i个数字的时候,这个数字要被选择的话又两种可能,一是第i个数没有被选中(概率是1-m/i),二是第i个数倍选中了(概率是m/i)但是替换掉的数字不是它(概率是1-1/m),于是这个数在第i个数时仍然被选择的概率是m/(i-1) * ((1-m/i) + (m/i * (1-1/m))) = m / (i-1) * ((i-1) / i) = m/i。

由数学归纳法原理知,对于任意的n,当给完n个数的时候,选择的结果可以保证这n个数中每个被选中的概率都是相等

给你一个数组,设计一个既高效又公平的方法随机打乱这个数组

基本思想是每次随机从i到n中取一个数,然后把它交换到i的位置。

证明:一个元素m被放入第i个位置的概率P = 前i-1个位置选择元素时没有选中m的概率 * 第i个位置选中m的概率,即:
在这里插入图片描述

疯子坐飞机问题

转自
100人坐飞机,第一个乘客在座位中随便选一个坐下,第100人正确坐到自己坐位的概率是?
他们分别拿到了从1号到100号的座位,这些乘客会按号码顺序登机并应当对号入座,如果他们发现对应号座位被别人坐了,就会在剩下空的座位随便挑一个坐.现在假设1号乘客疯了(其他人没疯),他会在100个座位中随便选一个座位坐下,问:第100人正确坐到自己坐位的概率是多少?(也可推广到n名乘客n个座位的情况)

我们把这个问题叫做「疯子问题」。疯子问题是指:有 n 位乘客坐飞机,第一位乘客是疯子,会胡乱坐;后边的 n-1 位则按照自己的位置坐,如果被占就再随机选择另一个。求最后一个乘客坐对的概率。其中 n>1 。

我们看看疯子问题是如何转化的:

1.疯子坐对了

问题结束,所有人都可以坐对位置。

2.疯子坐错了,但并没有占据最后一个人的位置

假设疯子坐在了 k 号位置(1<k<n),那么从 2到 k-1 号都可以坐对位置,这个时候 k 号乘客进来了。他看到自己的位置被占了,于是重新选择一个位置就座。

注意!

也就是说,在这种情况下,除了 n 变小了,这个问题依然是一个疯子问题!只是 n 变成了 n-k+1 ,而这个第 k 号乘客就是新的「疯子」;而对于每一个疯子,他坐对的位置都是第一个疯子的那个位置。

3.疯子坐错了,而且坐在了最后一个人的位置上

问题结束,最后一个人不能坐在自己的位置上。

所以,第二个选项是无效的,它只是把问题中的n变小了,实质上等于没有做任何选择;且这个过程要么结束,要么会变成 n=2 的情况,这个情况下没有选项 2。

而只有 1 和 3 两个等概率的选项决定了最终结果,它们的概率分别为二分之一。

因此答案是二分之一。

——————————————————更深入的思考结果

其实这个问题还可以更简单。注意到在中间,如果任何一个随机选座位的人坐到了第一个疯子的位置,那么后边的所有人——当然包括最后一个人——就可以坐对。

因此最后一个人的位置只有两种可能:第一个疯子的,他自己的。

这两个位置又没有什么区别,也就是说在各种情况下都是对称的,所以它们的概率相等。

如果还是有问题,下边这个模型你一定能明白。

考虑一枚硬币,正面向上的概率为 1/n ,反面也是,立起来的概率为 (n-2)/n 。我们规定硬币立起来重新抛,但重新抛时,n会至少减小1。求结果为反面的概率。

这样很显然结果为 1/2 。而「正面向上」对应的是下一个疯子坐最后一个人的座位(选项 I);「反面向上」对应下一个疯子坐对的情况(选项 III );「立起来」则对应坐在中间的情况(选项 II)。

圆内接三角形是锐角三角形概率是多少

在这里插入图片描述
圆固定,分为上下两部;三角形固定底边和定点就确定了,底边落在水平直径上方和下方的概率均为1/2,顶点落在水平直径上下方的概率也是1/2,锐角三角形的条件是底边和顶点落在不同方,所以1/2*1/2为1/4。

一条长度为l的线段,随机在其上选2个点,将线段分为3段,问这3个子段能组成一个三角形的概率是多少

设随机选取的两个数为x,y,并令y>x,则把长度为1的线段截得的三段长度为x, y-x ,1-y,根据三角形两边和大于第三边以及两边之差小于第三边的定理,可以列出方程组 y>1-y; x<1-x; x+(1-y)>y-x; 即x<1/2; y>1/2; y>x+1/2;画图可以算得概率为1/8

三只骰子掷出10概率多少?

总情况:共有666=216种
结果分两类(1)三个骰子结果不同:1,3,6 ;1,4,5 ;2,3,5
共有33!=18种结果
(2)其中两个结果相同:2,2,6; 2,4,4; 3,3,4
共有3
3=9中结果
18+9=27
所以总概率为27/216=1/8=0.125

扔骰子,1-2对方赢,3-5 自己赢,6重新仍,问自己赢的概率

3/5

如何通过3L和5L的水构造N升的水?

N=4L的时候:将5L倒满,用5L往3L倒满(此时5L剩2L),将3L杯子水倒掉,将5L中剩余的2L水倒入3L中,将5L倒满(此时3L杯中有2L水),用5L向3L倒把3L倒满,5L杯子内的水就是4L。

如果一个人在公路上半小时遇到车的概率是0.9,那么10分钟之内遇到汽车的概率的是多少?

设答案为x,则(1-x)^3=1-0.9求出答案即为x

烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一个小时十五分钟呢?

把第一根绳子两头同时点燃,同时把第二根绳子点燃一头,当第一根绳子烧完时,时间为半个小时,这时把第二根绳子的另一头也点燃,开始计时,当第二根绳子烧完时,停止计时,那么这段时间就是15分钟.

你有一桶果冻,其中有黄色、绿色、红色三种,闭上眼睛抓取同种颜色的两个。抓取多少个就可以确定你肯定有两个同一颜色的果冻?

四个。如果抓了3个,可能每个颜色各一个,当抓到第四个则一定会有两个小球颜色一致。

在半径为1的圆中随机选取一点。

在x轴[-1,1],y轴[-1,1]的正方形随机选取一点,如果此点在圆内,则即为所求的点。如果不在圆内,则重新随机直到选到了为止。

抛一个六面的色子,连续抛直到抛到6为止,问期望的抛的次数是多少。

方法一:因为每次抛到6的概率相等,都是1/6,于是期望的次数就是1/(1/6)=6次。
方法二:假设期望的次数为E。考虑第一次抛,如果已经抛到6了(概率为1/6),那么就不用再抛了。如果没抛到6(概率为5/6),那么还需要继续抛,可是还要抛多少次呢?显然,现在开始知道抛到6的次数仍然是E,但是刚刚已经抛了一次了于是可以得到这个等式
E = 1 * 1/6 + (1 + E) * 5/6,
解得 E = 6。即期望的次数为6次。

一个木桶里面有M个白球,每分钟从桶中随机取出一个球涂成红色(无论白或红都涂红)再放回,问将桶中球全部涂红的期望时间是多少?

令桶中有i个红球后再把全部球涂红的期望时间为a[i],此时再取出一个球,如果是红色的(概率为i/M),则直接放回,且剩余的期望时间仍是a[i]。如果是白色的(概率为1-i/M),则涂红后放回,剩余的期望时间为a[i+1],则
a[i] = (1 + a[i]) * i/M + (1 + a[i+1]) * (1 – i/M)
即   a[i] = a[i+1] + M/(M-i)
显然,有a[M] = 0
可以解得 a[0] = M/M + M/(M-1) + … + M/1 + 0

你有一把宝剑。每使用一个宝石,有50%的概率会成功让宝剑升一级,50%的概率会失败。如果宝剑的级数大于等于5的话,那么失败会使得宝剑降1级。如果宝剑的级数小于5的话,失败没有效果。问题是:期望用多少个宝石可以让一把1级的宝剑升到9级?

问题比较简单,用a[i]表示从第i-1级升到第i级期望使用的宝石数量。
当i<=5时,因为不会降级,则期望的数量均为2,即a[2] = a[3] = a[4] = a[5] = 2
当i>5时,因为会降级,成功时一个宝石就够了,不成功时需要倒退一级,需要先使用a[i-1]个宝石先回到i-1级,再使用a[i]个宝石升到第i级,即
a[i] = 1 * 1/2 + (1 + a[i-1] + a[i]) * 1/2
即 a[i] = a[i-1] + 2
可知,a[6]= 4, a[7] = 6, a[8] = 8, a[9] = 10
则1级到9级需要的宝石数为 a[2]+…+a[9] = 36。

已知有个rand7()的函数,返回1到7随机自然数,怎样利用这个rand7()构造rand10(),随机1~10。

产生随机数的主要原则是每个数出现的概率是相等的,如果可以得到一组等概率出现的数字,那么就可以从中找到映射为1~10的方法。
rand7()返回1~7的自然数,构造新的函数 (rand7()-1)*7 + rand7(),这个函数会随机产生1~49的自然数。原因是 1   49 1~49 1 49中的每个数只有唯一的第一个rand7()的值和第二个rand7()的值表示,于是它们出现的概率是相等。
但是这里的数字太多,可以丢弃

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值