最近在看演算法導論時,看到了這道晶元測試的題,想了很久,總結一下我的思路
diogenes教授有n個被認為是完全相同的vlsi晶元,原則上它們是可以互相測試的。教授的測試裝置一次可測二片,當該裝置中放有兩片晶元時,每一片就對另一片作測試並報告其好壞。乙個好的晶元總是能夠報告另一片的好壞,但乙個壞的晶元的結果是不可靠的。這樣,每次測試的四種可能結果如下:
a晶元報告
b晶元報告
結論b是好的
a是好的
都是好的,或都是壞的
b是好的
a是壞的
至少一片是壞的
b是壞的
a是好的
至少一片是壞的
b是壞的
a是壞的
至少一片是壞的
a)證明若多於n/2的晶元是壞的,在這種成對測試方法下,使用任何策略都不能確定哪個晶元是好的。假設壞的晶元可以聯合起來欺騙教授。
b)假設有多於n/2的晶元是好的,考慮從n片中找出一片好晶元的問題。證明n/2對測試就足以使問題的規模降至近原來的一半。
c)假設多於n/2片晶元是好的,證明好的晶元可用θ(n)對測試找出。給出並解答表示式測試次數的遞迴式。
當兩個晶元都報告是好的,如果其中乙個a是壞的,因為另乙個b說a是好的,所以b也是壞的
當兩個晶元的報告一好一壞時:
說對方好的那個晶元一定是壞的:假設a說b是好的,b說a是壞的,若a是好的,則b是好的,那麼b說a是壞的就自相矛盾了,所以a一定是壞的。
說對方壞的那個晶元可能是好的,也可能是壞的:經過上面的分析,a一定是壞的,那麼a說的就不可信(可能是對的可能是錯的),那麼b說a是壞的,b好的壞的都有可能
當兩個晶元的報告都是壞的時:
首先不可能兩個都是好的
若乙個是好的:假設a是好的,則a說b是壞的,成立;b是壞的,所以還不管b的說辭
兩個都是壞的,就無所謂他們說啥了
對於問題a,採用窮舉法,將任何一片晶元與其它所有晶元進行比較,因為有多於n/2的晶元是壞的,且壞的晶元可以聯合起來欺騙教授,則測試結果是不可靠的,無法判斷出該晶元是好是壞。
對於問題b和c,先假設:設有a
個好的晶元數,b
個壞的晶元數,z
對測試結果為全好的測試對,其中晶元(注意這裡是晶元全為好的,不是測試結果為好的)全是好的測試對為x
,晶元全為壞的測試對為y
,x+y=z
。
這裡先說明一下前提:好晶元比壞晶元至少多1片!(以下例子,想不明白可以假設總共有4片或者6片晶元)
一、隨機的兩兩配對,則共有⌊n/2⌋
對,分別測試。
二、根據問題描述:
(1)如果測試結果為一好一壞,或者兩壞,那麼把這對丟棄:
(3)這裡要考慮晶元為奇數的情況:
這樣操作後,留下的好晶元數一定還是大於壞的晶元數的,且經過⌊n/2⌋
對測試後,原問題的規模降低了近一半(解決了問題(b))。
三、 重複第(二)步,當n<=2時,就只剩下了好的晶元。
因為始終是好晶元數多於壞晶元數,那麼當n<=2時,就只有好的晶元了
總結:
測試結果為一好一壞或者兩壞的晶元對中至少一片是壞的,把這對丟棄能保證剩下的晶元中好晶元的數量仍大於壞晶元的數量。
測試結果為全好的,這對晶元有可能全為好,有可能全為壞,隨意丟棄其中乙個,留下 乙個。
設好晶元的對數為x,壞晶元的對數為y。考慮n的情況:
若n為偶數,則x>y,所以留下的好晶元數還是大於壞的晶元數;
若n為奇數,則剩餘乙個沒有配對的晶元。考慮z的情況:
若z是奇數,則x>y,丟棄這個晶元,這樣留下的好晶元數還是大於壞的晶元數;
若z是偶數,考慮這個晶元的情況:
若晶元是好的,則x>=y,留下這個好的晶元,這樣留下的好晶元數還是大於壞的晶元數;
若晶元是壞的,則x-y>=
2,留下這個壞的晶元,這樣留下的好晶元數還是大於壞的晶元數。
綜上所述,留下的好晶元數一定還是大於壞的晶元數的。
對於問題c:採用b中的操作方法,遞迴式為:f(n) = f(n/2) + n/2
。這個遞迴式符合主定理中的第三種情況,所以好的晶元可用θ(n)
對測試找出。
四、**實現
class
test
; system.out.
println
(arrays.
tostring
(getright
(arr,arr.length)))
;}//定義乙個測試平台,來模擬題幹中的測試裝置,好的晶元輸出對的,壞的晶元隨機輸出
public
static
boolean
judge
(int x,
int y)
else
if(x ==
1^ y ==1)
else
return result;
}//返回乙個正確的晶元
public
static
int[
]getright
(int
arr,
int length)
return z;
}//這裡用陣列儲存選出來的晶元,陣列定義為最壞情況下的長度,其它情況陣列後邊可能有多餘的位數
//所以用length來標明陣列中的有效長度
int[
] tmp =
newint
[length /2+
1];boolean
result = null;
//這個陣列用來接收測試結果
int point =0;
//記錄選出來的晶元個數
//晶元兩兩為一組,進行測試
for(
int i =
0; i < length-
1; i +=2)
}//考慮總個數為奇數的情況
if(length %2==
1)}//遞迴,繼續兩兩進行測試,直到晶元個數少於3個
return
getright
(tmp,point);}
}
晶元測試的分析(蠻力 分治)
說明 第一行 假設 a 是好的,那麼 b 是好的,則 a,b 都是好的。假設 a 是壞的,那麼 b 的報告結果不正確,那麼 b 就也是壞的,則 a,b 都是壞的。第二行 假設 a 是好的,那麼 b 的報告結果不正確,那麼 b 就也是壞的,此時一好一壞。假設 a 是壞的,b 的結果顯示 a 是壞的,但...
晶元測試及其應用(分治典例)
問題敘述 vlsi晶元測試 diogenes教授有n個被認為是完全相同的vlsi晶元,原則上它們是可以互相測試的。教授的測試裝置一次可測二片,當該裝置中放有兩片晶元 時,每一片就對另一片作測試並報告其好壞。乙個好的晶元總是能夠報告另一片的好壞,但乙個壞的晶元的結果是不可靠的。這樣,每次測試的四種可能...
分治法之棋盤覆蓋
一 問題描述 在乙個2k x 2k 即 2 k x 2 k 個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。在棋盤覆蓋問題中,要用圖示的 4種不同形態的 l型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個 l型骨牌不得重疊覆蓋。二 演算法思...