【算法】分治策略:芯片測試

目錄

算法背景分析

一次測試結果分析:

重要的假設

方法一:蠻力測試

方法二:分治策略          證明假設以及特殊處理

算法代碼

測試結果


算法背景分析

一次測試結果分析:

代碼:一次芯片的測試

     

重要的假設

好芯片至少比壞芯片多一片

方法一:蠻力測試

代碼:蠻力測試

方法二:分治策略

    

代碼:分治策略的淘汰規則

代碼:分治策略

證明假設

    

算法代碼

博主自己寫的,僅僅參考了講義的僞代碼,若有錯誤請指出,謝謝。

獲取芯片

import numpy as np
import math

# 獲取芯片
def getXin(size, label=[1,0]):
    """
    size: 芯片個數
    label: 芯片有好有壞,1:好,0:壞
    
    xin: 所有的芯片標籤
    """
    xin   = np.random.choice(label, size=size, replace=True)
    if sum(xin) < size/2:  # 好芯片個數至少要比壞芯片多1個
        xin   = 1 - xin
    
    return xin

一次芯片的測試

# 測試芯片好壞
def test(xin, a, b, label=[1,0]):
    """
    xin: 所有的芯片標籤
    a,b:用芯片A測試芯片B,芯片的序號
    label:芯片有好有壞,1:好,0:壞
    
    result: 返回芯片測試結果:芯片A是好芯片,返回芯片B的真實情況;芯片A是壞芯片,隨機返回結果
    """
    if xin[a] == label[0]:
        return xin[b]
    else:
        return np.random.choice(label, size=1)[0]

分治策略的淘汰規則

def deal(xin, a, b, label=[1,0]):
    # 測試
    aa = test(xin, a, b)
    bb = test(xin, b, a)
    summ = sum([aa, bb])
    if summ == 2: # 如果結果都是好,兩個要麼都是好芯片,要麼都是壞芯片,隨機留一個芯片
        return np.random.choice([a,b], size=1)[0]  # 隨機返回芯片序號 
    else:  # 全部丟棄
        return -1

蠻力測試

# 蠻力測試法
def rude(xin, b, label=[1,0]):
    res = []
    for a in range(len(xin)):
        if a != b :
            res.append(test(xin, a, b))
    
    # 若測試結果多於n/2個好,芯片b是好芯片
    if sum(res) > len(xin)/2:
        return 1
    else:
        return 0

分治策略

# 分治測試法
def divide(xin, index=[], label=[1,0]):
    """
    xin  : 所有的芯片標籤
    index: 芯片序號的列表,默認由np.arange(size)產生
    label:芯片有好有壞,1:好,0:壞
    """
    size = len(xin)
    if len(index) != size:
        index = np.arange(size)  # 記錄芯片序號
    
    while size > 3:
        temp=[]  # 緩存芯片序號
        if size%2 == 1: # 芯片個數爲奇數
            if rude(xin[index], -1) == 1:
                temp.append(index[-1])  # 壞芯片淘汰,好芯片放入下一回
                
            index = index[:-1]
            size -= 1
            
        # 兩兩測試,分組淘汰
        # print(xin[index], index)
        for i in range(int(size/2)):
            res = deal(xin, index[i*2], index[i*2+1])  # 測試結果一好一壞,返回-1;否則返回芯片序號
            if res != -1:
                temp.append(res)
            # print(index[i*2], index[i*2+1], temp, xin[temp])
        
        index = temp
        size = len(index)
        
    # 遞歸結束
    if size == 0:
        # size=0時,中間隨機出了一點問題,打亂芯片順序再來一次
        index = np.arange(len(xin))
        random.shuffle(index)
        i,_ = divide(xin, index)
    elif size == 3:
        # 測試前兩個芯片,若全好的,任取一片;否則取最後一個芯片
        if deal(xin, index[0], index[1]) == -1:
            i = index[2]
        else:
            i = np.random.choice(index[:-1], size=1)[0]
    else:  
        # 只有1/2個,都是好芯片,隨機取一個
        # 根據【重要假設:好芯片至少比壞芯片多一個】
        # 缺點:當size=2時,會出現[1,0],隨機選擇會出錯
        # 解決:size=2時,重新測試→這樣可能會陷入無限循環
        i = np.random.choice(index, size=1)[0]
        
    return i, xin[i]

測試

xin = getXin(10)
index, label = divide(xin)
print(xin)
print('輸出芯片序號:', index, ',現實標籤:', label)

測試結果

如果芯片個數是奇數,基本沒錯

如果芯片個數是偶數,會有0.5%的錯誤率。因爲最後的遞歸結果可能是[1,0],這樣隨機選擇有一半的錯誤率。

感覺只剩下兩個的時候,可以做一個蠻力測試。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章