問題敘述:
vlsi晶元測試
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)對測試找出。給出並解答表示式測試次數的遞迴式。
注:vlsi——very large scaleintegrated.
演算法分析:
a)採用窮舉法,將任何一片晶元與其它所有晶元進行比較,因為有多於n/2的晶元是壞的,且壞的晶元可以聯合起來欺騙教授,則測試結果是不可靠的,無法判斷出該晶元是好是壞。
b)假設:設有a個好的晶元數,b個壞的晶元數,z對測試結果為全好的測試對,其中晶元全為好的測試對為x,晶元全為壞的測試對為y,x+y=z。
二分測試思想:
1.隨機的兩兩配對,則共有⌊n/2⌋對,分別測試。
2.根據問題描述:如果測試結果為一好一壞,或者兩壞,那麼把這對丟棄;如果測試結果為兩好,那麼隨意丟棄其中乙個,留下乙個(若n為奇數,則剩餘乙個芯 片沒有配對。若z為奇數,丟棄這個晶元;若z為偶數(0也看做偶數),留下這個晶元)。這樣操作後,留下的好晶元數一定還是大於壞的晶元數的,且經過⌊n/2⌋對測試後,原問題的規模降低了近一半。
3.重複第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)對測試找出。
應用:
1.主元素:
何謂主元素?具體講,如果乙個陣列
a[1..n]
中超過半數的元素都相同時,該陣列被稱為含有乙個主元素。(a)
設計乙個有效演算法,確定該陣列中是否含有乙個主元素,如果有,找出這個元素。(b)
能否給出乙個線性時間演算法?
注意,該陣列的元素之間可能不存在順序
——即不能進行
」a[i]的大小判斷,但是可以進行是否相等的判斷。普通的演算法即需要2個
for迴圈,算出每個數字的個數,這比較簡單,這裡不再給出,時間複雜度為o(n^2)。
首先來看看如果可以比較大小:
平均時間複雜度為線性o(n),基於分治法的線性時間求主元素演算法。演算法思想中位數:數列排序後位於最中間的那個數。如果乙個數列有主元素,那麼必然是其中位數。求乙個數列有沒有主元素,只要看中位數是不是主元素。找中位數的方法:選擇乙個元素作為劃分起點,然後用快速排序的方法將小於它的移動到左邊,大於它的移動到右邊。這樣就將元素劃分為兩個部分。此時,劃分元素所在位置為k。如果k>n/2,那麼繼續用同樣的方法在左邊部分找;如果k平均時間複雜度為o(n)的時間內找出乙個數列的中位數,但最壞時間複雜度o(n^2)。然後再用o(n)的時間檢查它是否是主元素。。c語言原始碼如下:
int partition(int a,int low,int high)
if(low++low;
if(lowa[high]=a[low];
--high;
}
}
a[low]=pivotkey;
return low;}
//快排
void quick_sort(int a,int low,int high)
}
int main()
for(int i=1;i<=n;i++)
quick_sort(a,1,n);
int count=0;
for(int i=1;i<=n;i++)//中位數個數
if(count > n / 2)
printf("有主元素為 %d 出現了 %d 次\n",mid,count);
else
printf("無主元素\n");
system("pause");
}
下面來看如果不可以比較大小只可以比較是否相等的情況:
下面來看看如果無序,不能比較大小的演算法,具體思想就是
「在乙個集合中,刪除兩個不同的數,則集合的主元素保持不變。
」根據這個原理,可以很快求出主元素。只有最後剩下的元素才可能是主元素。
#include
int getmainelement(int a,int len)
else
}
return mainelement;
}
int main()
mainelement = getmainelement(a,len);
for(i = 0;iif(mainelement == a[i])
flagcount++;
}
if(flagcount>len/2)
printf("%d\n",mainelement);
else
printf("none\n");
}
return 0;
}
2.有n個人,其中某些人是誠實的,某些人可能會說謊。現在需要進行一項調查,該調查由一系列測試構成。每次測試如下進行:選2個人,然後提問:對方是否誠實?每個人的回答只能是「是」或者「否」。假定在這些人中,所有誠實的人回答都是正確的,而其他人的回答則不能肯定是否正確。如果誠實的人數》n/2,試設計乙個調查演算法,以最小的測試次數從其中找出乙個誠實的人。
分治法之晶元測試
最近在看演算法導論時,看到了這道晶元測試的題,想了很久,總結一下我的思路 diogenes教授有n個被認為是完全相同的vlsi晶元,原則上它們是可以互相測試的。教授的測試裝置一次可測二片,當該裝置中放有兩片晶元時,每一片就對另一片作測試並報告其好壞。乙個好的晶元總是能夠報告另一片的好壞,但乙個壞的晶...
晶元測試的分析(蠻力 分治)
說明 第一行 假設 a 是好的,那麼 b 是好的,則 a,b 都是好的。假設 a 是壞的,那麼 b 的報告結果不正確,那麼 b 就也是壞的,則 a,b 都是壞的。第二行 假設 a 是好的,那麼 b 的報告結果不正確,那麼 b 就也是壞的,此時一好一壞。假設 a 是壞的,b 的結果顯示 a 是壞的,但...
遞迴和分治思想及其應用
更多 如果可以使用迭代,盡量別使用遞迴。由編譯原理可以知道,每次自呼叫的時候,計算機都需要儲存在呼叫,浪費時間空間。當然,迭代是當我們知道迴圈次數的時候。而當我們不知道迴圈次數,比如說對於資料夾和檔案進行遍歷,不知道深度的情況下,我們就需要遞迴來實現。顯然,遞迴是先解決小的問題,這種思想是分治思想。...