阿里一道笔试题目:一跟木棍随机分成四段,放在黑盒中,随机从中拿出三段求能构成三角形的概率

先考虑分成三段的情况:设线段长度为a,任意分成三段长分别为x,y和a-x-y,显然有x>0,y>0,a-x-y>0,将这三个约束条件画到(x,y)二维平面坐标系上,能构成三角形的约束条件为:

x + y > a - x - y  (x + y < a/2)

x + a - x - y > y  (y < a/2)

y + a - x - y > x  (x < a/2) 

以上为数学解法,正确答案为1/4。

计算机专业的就想用编程的想法来解决(贴一下解决问题的思路

开始是这样想的

import random
res = 0

for _ in range(100000):
    a = random.random()
    b = random.uniform(0, 1 - a)
    c = 1 - a - b

    if a + b > c and a + c > b and b + c > a:
        res += 1

print(res / 100000)

结果为

a为0-1的随机浮点数,b为0-(1-a)的随机浮点数,c为剩下的一段。这样求得的结果为0.19左右,翻了会儿资料发现挺多人都得到过这个错误的结果,还有人说是它就是对的,什么ln2-0.5=0.19,也有人说是因为计算机的伪随机导致的,神乎其神。这样做法不对的地方在于,首先随机产生一个a值,如果将b设为0到(0-a),a和b就产生了关联,有种条件概率的意思,假设a的值很大接近1,b的可取范围就变小了很多,每次a都是随机,a本身取值的概率是一样的,但是对于不同a,b取值的概率是不同的,就产生了错误了结果。

正确的做法是:在(0<a<1, 0<b<1)的范围内随机取点,对于属于下三角范围内(上图所示)的点(0<a<1, 0<b<1,a+b<1)才进行考虑,否则丢弃。

import random
res = 0
legal = 0

for _ in range(100000):
    a = random.random()
    b = random.random()
    c = 1 - a - b

    if c > 0:
        legal += 1

        if a + b > c and a + c > b and b + c > a:
            res += 1

print(res / legal)

结果为

设置一个legal值,当a+b<1时候,才进行考虑

顺着这个思路往下模拟分成四段的情况

import random
res = 0
legal = 0

for _ in range(100000):
    a = random.random()
    b = random.random()
    c = random.random()
    d = 1 - a - b - c

    if d > 0:
        legal += 1

        dic = {1: a, 2: b, 3: c, 4: d}
        x = dic[random.choice([1, 2, 3, 4])]

        left = list({a, b, c, d} - {x})
        if left[0] + left[1] > left[2] and left[0] + left[2] > left[1] and left[1] + left[2] > left[0]:
            res += 1

print(res / legal)

得到的结果为

因为不知道标准答案,也不知道上述过程是否有错,欢迎各位大佬指点。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值