老鼠毒药问题和它的扩展

这是一个传播得非常广的问题:有1000瓶液体,其中一瓶是毒药,其他的都是清水。毒药看上去和水一样,只能用老鼠来试验。老鼠在喝了毒药以后一个星期后一天内的任意时刻死亡。最少需要多少只老鼠才能找到毒药?


n瓶液体当中一瓶有毒,总共有n种可能性,用集合N来表示。

一只老鼠的生死可以用0、1表示。

r只老鼠的生死构成了一个0、1串,这个0、1串可以表示2的r次方中结果,用集合R表示。

我们就是要找一个实验方法,通过这些老鼠的生死获取毒药的编号。

如果做个抽象,这个实验方法是F,F把N中元素分别映射到R上。我们从R中的结果可以推测出这个N中元素。

所以R中的元素需要和N中的元素相等。因此2的r次方等于n,  r = log(n)。

回到这个问题上来,理论上,我们需要10只老鼠才能找出隐藏的毒药。


具体来说应该怎么操作呢,也就是我们要寻找一种算法。以及这种算法是否能只用10只老鼠就找到1000当中的毒药呢?

如果有一只老鼠,我们可以让它喝一半的药水。它的生死就能确定毒药在哪一半。

例如n = 8。

              000 001 010 011 100 101 110 111

老鼠a                                 1     1     1     1

老鼠a喝下编号为5到8的所有药水以后,如果毒药在右半边,老鼠死;否则,老鼠活。

如果用二进制去编码药水,一只老鼠的生死可以指示这一瓶毒药某一位是0,还是1

最后的实验方案是这样的

              000 001 010 011 100 101 110 111

a                                  1     1     1     1

        b                    1      1                  1     1

        c              1            1           1            1

不同的老鼠喝下自己一行中标注为1的药水

如果是1000瓶药水,依次用二进制表示。依照上面的方式我们可以用10只老鼠来找到唯一的毒药。


下面重点说下这个问题的拓展。

如果1000瓶液体当中有两瓶毒药,最少需要的老鼠是多少呢,应该如何操作?

根据前面的方法,我们先计算理论上的下界。

毒药的分布总共有C(1000,2)中情况,我们最少需要19只老鼠。


首先把毒药平均分成两组,如何确定毒药在哪一组呢?

例如:

A:   000 001 010 011

B:   100 101 110 111

一只老鼠是不够的

我们用两只老鼠a,b。a喝下A组,b喝下B组。

如果两只老鼠全部死去,我们可以确定毒药分别在A、B当中。如果老鼠只有一只死去,我们可以确定两瓶毒药在同一组里

也就是说通过上诉方法,我们可以确定毒药编号的二进制表示的第1位的状况(都是1,都是0,分别是0、1)


这个方法能否确定第2位的状态呢?

答案是能。

但是存在一个问题。

如果第1位分别是0、1,第2位也分别是0、1,那么这两个瓶的编号是00、11,还是01、10呢?


如何解决这个问题呢?

如果我们知道两瓶毒药的编号的第1位是不同的

例如:

A:   000 001 010 011

B:   100 101 110 111

毒药1在A组,毒药2在B组,那么这个问题就变成了寻找一瓶毒药的问题。针对n=8的情况,我们可以再使用2对老鼠就能找到两瓶毒药的编号。

如果我们有两周试验的机会,可以第一周先用2对老鼠(为什么是2对?)找到毒药编号哪一位是不同的。在知道哪一位不同以后,在第二周用2对老鼠得到两瓶毒药的其他位值。也就是说我们可以用2*log2(n/2)+2*log(n/2) 只老鼠在两轮试验的情况下找到两瓶毒药


但是我们只允许有1轮试验时间,如何解决呢?

既然不能猜,我们就全押好了。

对于n=8的情况,两瓶毒药的编号,可能在1、2、3位不同。总是有一位不同,也有可能好几位不同。

我们先押第1位不同,也就是两瓶毒药分别在A、B组当中:

A:   000 001 010 011

B:   100 101 110 111

用2对老鼠分别测试A、B组毒药。


再押第2位不同,两瓶毒药分别在C、D组中:

C: 000 001 100 101  

D: 010 011 110 111

也是用两对老鼠


再押第3位不同,分别在E、F组:

E: 000 010 100 110

F: 001 011 101 111


那么这样测试的结果会如何呢?

假设两瓶毒药编号在第3位相同。

比如是010, 100,那么E、F两组测试的结果是F组的老鼠全部存活下来;

如果是011, 111,那么E、F两组的测试结果是E组的老鼠全部存活。

所以第3位不相同的假设是不成立的。

也就是说哪一位如果是相同的,针对那一位做的实验会出现一组当中全部存活的情况。因此这两组针对这一位的实验是无效的。


如果两瓶毒药在第1位是不同的,

例如毒药编号是011、100,那么A、B组当中都会出现死亡,那么第1位不同的假设是成立的,我们可以得到各个位的值。


综上所述在猜测某一位不同时,我们需要2*log(n/2)只老鼠;要押中所有位的话,我们需要log(n)*2*log(n/2)只老鼠。

也就是说,如果n=1000,有两瓶毒药。用上述方法,我们需要(10*2*9)180只老鼠,才能找出毒药编号。

离我们的下界19有些远。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值