【算法】分治策略:芯片测试

目录

算法背景分析

一次测试结果分析:

重要的假设

方法一:蛮力测试

方法二:分治策略          证明假设以及特殊处理

算法代码

测试结果


算法背景分析

一次测试结果分析:

代码:一次芯片的测试

     

重要的假设

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

方法一:蛮力测试

代码:蛮力测试

方法二:分治策略

    

代码:分治策略的淘汰规则

代码:分治策略

证明假设

    

算法代码

博主自己写的,仅仅参考了讲义的伪代码,若有错误请指出,谢谢。

获取芯片

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],这样随机选择有一半的错误率。

感觉只剩下两个的时候,可以做一个蛮力测试。

 

分治算法是一种常见的递归算法策略,它将一个复杂的问题分解成规模较小的相似子问题,然后分别解决这些子问题,最后合并子问题的解得到原问题的解。这种方法通常用于解决可以被分割为独立部分并分别处理的问题,如排序、搜索和计算等。 对于判断芯片的好坏,假设我们有一个简单的场景,比如检查一组特定属性(如电压、温度、频率等)。我们可以编写一个Python函数,采用分治思想,将其划分为两个步骤: 1. **划分**(Divide):将芯片的数据集分成两半,对每个子集独立进行检测。 2. **解决**(Conquer):递归地应用同样的过程到子集上,检查它们是否满足好芯片的条件。 3. **合并结果**(Combine):当所有子集都检查完毕后,如果所有子集的芯片都合格,则整体认为这块芯片是好的;如果有任何一个子集不符合要求,那么整个芯片就判断为不合格。 ```python def is_good_chip(data): # 如果数据只有一个元素,直接判断其是否符合条件 if len(data) == 1: return check_single_chip(data[0]) # 将数据一分为二 mid = len(data) // 2 left_half = data[:mid] right_half = data[mid:] # 递归检查左右两部分 is_left_good = is_good_chip(left_half) is_right_good = is_good_chip(right_half) # 合并子问题的结果 return is_left_good and is_right_good # 检查单个芯片的方法(这里仅做示例) def check_single_chip(chip_data): # 根据实际的芯片属性定义的好坏标准填写此函数 pass # 示例用法 chip_test_data = [5V, 60Hz, 40°C] # 假设这是芯片的一些测试数据 is_chip_good = is_good_chip(chip_test_data) ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值