文章目录
1. 问题引入
- 一次测试过程
假设: - 好芯片的报告一定是正确的
- 坏芯片的报告是不确定的
测试结果分析
- 每一种报道都可能A,B都是坏芯片
- 而只有第一种情况才有可能A,B都是好的
2. 如何在n个芯片里面判断A芯片是不是好芯片?
输入:
n片芯片,其中好芯片至少比坏芯片多一片
问题
设计一种测试方法,找出一片好芯片
2.1 例:假设 n = 7,好芯片数 >= 4.
那么除去A,还有 6 个芯片,我们要拿其余 6 个芯片分别与A芯片进行测试
注意:
- 是看其余 6 个芯片对A的测试结果,不是A对其余 6 个芯片的测试结果
结果:
- 6个报告中至少 3 个报A是好的,则A好
- 6个报告中至少 4 个报A是坏的,则A坏
结论:
- 当n为奇数,且好芯片数>=(n+1)/2.
- A好,至少有(n-1)/2个报告为好
- A坏,至少有(n+1)/2个报告为坏
2.2 例:假设 n = 8:好芯片数 >= 5.
同理得到结论:
- 当n为偶数:好芯片数 >= n/2 + 1.
- A好,至少有n/2个报告为好
- A坏,至少有n/(2+1)个报告为坏
3. 如何在n个芯片里面找到一个好芯片?
3.1 蛮力算法
测试一个芯片是不是好芯片参考目录2的方法
- 时间估计最长:
- 第一片坏芯片,最多测试n-2次(当测试结果为 坏 好 坏 好…)
- 第二片坏芯片,同上测试n-3次
- …
共:n-2 + n-3 + n-4 + … +2
- 总计: Θ(n2)
3.2 分治算法
3.2.1 n为偶数时分治过程
把 n 个芯片两两分为一组,那么一共可以分 n/2 个组
对于其中一组来说(参考目录1问题引入)
- 若结果都报好,则要么这 2 片芯片都好,要么都坏,所以只挑其中一个芯片进行下一轮测试
- 若是其他情况,则至少有一个芯片是坏的,就把两片芯片都丢掉
- 那么经过一次分组测试下来,问题规模变为原来的一半
- 那么执行一次上述操作,芯片规模至少会减少一半
3.2.1.1 递归截止条件: n <= 3
- 3片芯片,1次测试可以得到好芯片
- 1或2片芯片,不需要再测试
原因: 原问题描述为好芯片个数比坏芯片个数大,要用分治思想,那么分治之后子问题性质不变(下面证明)
3.2.1.2 分治算法正确性
证明:n为偶数时,经过一轮淘汰,剩下的好芯片比坏芯片至少多一片
设:A,B都好的芯片有 i 组,A与B一好一坏的芯片有j组,A与B都坏的有k组
- 初始: 总数为 n = 2i +2j +2k
- 且 2i + j > 2k +j (好芯片比坏芯片至少多一片)
得到 i > k
而经过一轮递归后
- i组:保留i个好芯片
- j组:全部淘汰
- k组:最多保留k个坏芯片 (k组全报告正确的时候)
- 此时下一轮中,保留了n = i 个好芯片 + 最多 k 个坏芯片
- 我们要证明:剩下的芯片中,好芯片个数比坏芯片个数大,即 i>k,得证
此时,n为偶数时已经证明完全正确,下面处理n为奇数的情况
3.2.2 n为奇数时处理
- 这里不符合好的芯片比坏的多
所以
单独测试: 同 目录2 如何在n个芯片里面判断A芯片是不是好芯片 一样 - 最多需要测试 O(n)次
因此,整个过程为
T(n) = T(n/2) + O(n)
T(3) = 1
T(2) = T(1) = 0
得到T(n) = O(n)