算法设计与分析:芯片测试问题、选择问题详解
芯片測試問題
有n片芯片,已知其中好芯片比壞芯片至少多1片。現(xiàn)在需要通過測試從中找出1片好芯片。測試的方法是:將2片芯片放到測試臺(tái)上,2片芯片互相測試并報(bào)告測試結(jié)果:”好”或者”壞”。假定好芯片的報(bào)告是正確的,壞芯片的報(bào)告是不可靠的(可能是對(duì)的,也可能是錯(cuò)的)。請(qǐng)?jiān)O(shè)計(jì)一個(gè)算法,使用最少的測試次數(shù)來找出1片好芯片。
由于好芯片至少比壞芯片多1片,對(duì)1片芯片來說,如果有?n/2?片芯片都報(bào)告它是”好的”,那么這片芯片一定是好的(因?yàn)槿绻撔酒乃袌?bào)告都是壞芯片產(chǎn)生的,則說明已經(jīng)有?n/2?個(gè)壞芯片,又因?yàn)楹眯酒葔男酒?#xff0c;所以當(dāng)前芯片一定是好的;而如果并非所有報(bào)告都是壞芯片產(chǎn)生的,那么有些報(bào)告是好芯片產(chǎn)生的,所以當(dāng)前芯片一定是好的)。一個(gè)蠻力算法就是任取1片芯片,然后用其余所有芯片來測試它,直到找到1片好芯片為止。這個(gè)算法最壞情況下Θ(n^2)次測試。
下面嘗試一下分治策略。
初始的想法就是:將n片芯片兩兩一組分成?n/2?組,每組測試1次。就像體育比賽的淘汰賽一樣,通過第一輪的?n/2?次測試淘汰一部分芯片,剩下的芯片構(gòu)成一個(gè)規(guī)模較小的子問題進(jìn)入第二輪。如果測試的芯片不超過3片(即子問題規(guī)模小于等于3),并且好芯片比壞芯片至少多1片,那么只要測試1次就可以找出好芯片。剩下需要考慮的一個(gè)問題是:采取什么樣的淘汰規(guī)則,能夠保證進(jìn)入下一輪的好芯片比壞芯片至少多一片,換句話說,每輪測試丟棄的壞芯片數(shù)至少和丟棄的好芯片數(shù)一樣多。這涉及算法的正確性。另一個(gè)問題是:每輪測試淘汰的芯片數(shù)占測試芯片數(shù)的比例是多少。這涉及子問題規(guī)模縮小得有多快,它決定了算法的效率。
先分析一下不同的測試報(bào)告究竟給出了什么信息。假設(shè)放到測試臺(tái)上的芯片是A和B,表1列出了可能的結(jié)果。
- 如果測試結(jié)果是情況1,那么A、B中留1片,任意丟掉1片(實(shí)際上A、B都好或A、B都?jí)?#xff09;;
- 如果是后三種情況,則把A和B全部丟掉(實(shí)際上因?yàn)橹辽儆幸黄呛玫?#xff0c;因此最差的情況是好壞芯片同歸于盡,但至少?zèng)]有多丟掉好芯片)。
命題 1 當(dāng)n是偶數(shù)時(shí),在上述規(guī)則下,經(jīng)過一輪淘汰,剩下的好芯片比壞芯片至少多1片。
證 設(shè)A、B都是好芯片的有i組,A、B一好一壞有j組,A、B都?jí)牡挠衚組,那么
經(jīng)過淘汰后,剩下好芯片數(shù)為i,壞芯片數(shù)為k,滿足i>k。
但是當(dāng)n是奇數(shù),沒被分組而輪空的是1片壞芯片時(shí),可能淘汰后剩下的好芯片與壞芯片數(shù)相等。比如n=7,有4片好芯片,3片壞芯片。如果分組為:{好,好},{好,好},{壞,壞},1片壞芯片輪空,那么淘汰后的4片芯片恰好2好2壞。對(duì)于奇數(shù)的情況,可以增加一輪特殊處理,即把這個(gè)輪空的芯片與每1片其他芯片都測一遍。根據(jù)前面的分析,通過這些測試可以判斷這片芯片的好壞。如果它是好的,算法結(jié)束;如果它是壞的,丟棄它。這些額外工作需要O(n)次測試,而這輪分組內(nèi)的測試也需要O(n)次(精確說應(yīng)該是?n/2?次),因此不論是偶數(shù)還是奇數(shù),歸約為子問題的工作量都是O(n)。
下面考慮第二個(gè)問題。
命題2 因?yàn)槊拷M至少需要丟掉1片芯片,因此經(jīng)過一輪測試后,剩下的芯片數(shù)至多為n/2。算法的偽碼描述如下:
根據(jù)前面關(guān)于遞推方程的分析結(jié)果,可以得到 。不難看出,比起蠻力算法,分治算法在效率上有明顯的提高。
選擇問題
1、同時(shí)選最大和最小算法
該算法的基本思想是:首先將L中的元素兩兩一組,分成?n/2?組(當(dāng)n是奇數(shù)時(shí)有一個(gè)元素輪空)。每組中的兩個(gè)數(shù)通過1次比較確定本組的”較大”和”較小”。把至多?n/2?+1(當(dāng)n為奇數(shù)時(shí),需要把被輪空的元素加進(jìn)來)個(gè)小組”較大”放到一起,運(yùn)行Findmax算法找出其中的最大元素,它就是L中的最大元素。類似地,再把至多?n/2?+1(當(dāng)n為奇數(shù)時(shí),需要把輪空的元素加進(jìn)來)個(gè)小組”較小”放到一起,運(yùn)行Findmin算法找出其中的最小元素,它就是L中的最小元素。
該算法的偽碼描述如下:
2、找第二大元素的算法
顯然兩次調(diào)用Findmax算法可以得到第二大元素,先用Findmax算法找出最大元素,然后從L中刪除max,再調(diào)用Findmax找出剩下元素的最大元素,就是輸入L的第二大元素Second。不難看出該算法的時(shí)間復(fù)雜度是:
下面嘗試錦標(biāo)賽算法。該算法的基本思想是:將L中的元素兩兩一組,分成?n/2?組(如果n是奇數(shù)時(shí)可能有1個(gè)元素輪空)。每組內(nèi)進(jìn)行比較,將較小的元素淘汰,每組中較大的元素和輪空的元素(如果存在的話)進(jìn)入下一輪。進(jìn)入下一輪的元素應(yīng)該有?n/2?個(gè)。在下一輪中,繼續(xù)進(jìn)行同樣的分組淘汰,勝者再進(jìn)入下一輪,直到產(chǎn)生”冠軍”,即最大元素為止。到此算法總計(jì)淘汰了n-1個(gè)元素,每次比較恰好淘汰1個(gè)元素,因此算法已經(jīng)做了n-1次比較。但是,我們的任務(wù)還沒有完成,怎樣找第二大元素Second呢? 如果還是再次調(diào)用找最大算法,那么算法還需要n-2次比較。這就和剛才的兩次調(diào)用Findmax的算法在時(shí)間上一樣了。我們的想法是:利用第一階段競爭冠軍時(shí)比較運(yùn)算的結(jié)果信息,以減少第二階段的比較次數(shù)。這是可能的。首先觀察到,第二大元素只能在與最大元素max直接比較所淘汰的元素中產(chǎn)生。如果一個(gè)元素被其他元素淘汰,而那個(gè)元素本身不是冠軍,那么該元素至多只能排在第三名之后。這樣,我們?cè)谡业诙笤貢r(shí)只需關(guān)心那些被max淘汰的元素即可。需要考慮的是在第一階段中,被max淘汰的元素有多少,又是哪些元素。在max沒產(chǎn)生之前,算法并不知道誰是最后的冠軍,我們必須要求每個(gè)元素把被自己淘汰掉的元素全部記錄下來。為此,在比賽之前為每個(gè)元素設(shè)定一個(gè)指針,指向一個(gè)鏈表。如果該元素在比較中把其他元素淘汰了,就把那個(gè)元素記錄在自己的鏈表里。到max產(chǎn)生的時(shí)候,我們只需要檢查max的鏈表,在上面調(diào)用Findmax 算法就可以找到第二大元素了。算法的偽碼描述如下:
這個(gè)算法的時(shí)間復(fù)雜度是多少? 算法所做的比較次數(shù)分成兩部分,第一部分是找最大元素max過程中的比較次數(shù),第二部分是在產(chǎn)生max后在其鏈表中找最大所需要的比較次數(shù)。在第一部分,每次比較正好淘汰1個(gè)元素,淘汰n-1個(gè)元素的比較次數(shù)就等于n-1。在第二部分,比較次數(shù)恰好等于max 鏈表中的元素個(gè)數(shù)減1,只要估計(jì)出max 所淘汰掉的元素個(gè)數(shù)就可以得到這部分的工作量。
我們有下面的命題:
總結(jié)
以上是生活随笔為你收集整理的算法设计与分析:芯片测试问题、选择问题详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode 229. Majori
- 下一篇: leetcode 260. Single