4. 规则驱动型排产(一):先入先出(FIFO)、最短加工时间(SPT)、最早交货期(EDD)的原理与实现

各位工程师朋友,今天我们聊聊排产算法里最基础、也最实用的三类规则。说实话,很多刚入行的同事总觉得排产必须上AI、上遗传算法才够高级。我个人习惯是:能用简单规则解决的问题,绝不上复杂模型。你想想看,工厂里每天几千个lot在跑,如果每个决策都要算十分钟,那黄花菜都凉了。

4.1 先入先出(FIFO)——最朴素的公平

FIFO,说白了就是谁先来谁先做。这个规则在半导体工厂里应用极广,尤其是光刻区、扩散区这些瓶颈工序。我记得刚入行时带我的老师傅说:「别小看FIFO,它能让你的WIP分布最均匀。」

原理:按照lot到达当前设备的时间戳排序,最早到达的优先加工。

适用场景

  • 设备负载均衡要求高
  • 产品种类单一,工艺时间差异不大
  • 客户对交期没有特殊要求

核心公式:优先级 = ArrivalTime(lot) ,值越小优先级越高。

代码实现(Python伪代码)

def fifo_schedule(lots, machine):
    # lots: list of dict, 每个lot包含lot_id, arrival_time, process_time
    # 按到达时间排序
    sorted_lots = sorted(lots, key=lambda x: x['arrival_time'])
    
    schedule = []
    current_time = 0
    for lot in sorted_lots:
        start_time = max(current_time, lot['arrival_time'])
        end_time = start_time + lot['process_time']
        schedule.append({
            'lot_id': lot['lot_id'],
            'start': start_time,
            'end': end_time
        })
        current_time = end_time
    return schedule

避坑指南:我曾经在一个项目中直接用FIFO排产,结果发现某个lot的工艺时间特别长,导致后面所有lot都延迟了。后来我加了一个「超时打断」机制——如果某个lot加工时间超过阈值,就暂时挂起,先处理后面的短lot。嗯,这里要注意,FIFO不是万能的。

4.2 最短加工时间(SPT)——效率优先

SPT规则,顾名思义,加工时间最短的lot优先。这个规则的目标很明确:最小化平均流程时间。说白了就是让更多的lot尽快做完,提高设备利用率。

原理:比较每个lot在当前设备上的加工时间,选最小的先做。

适用场景

  • 设备是瓶颈,需要最大化产出
  • 产品工艺时间差异大(比如有5分钟和5小时的lot混在一起)
  • 对交期要求不严格

核心公式:优先级 = ProcessTime(lot) ,值越小优先级越高。

代码实现

def spt_schedule(lots, machine):
    # 按加工时间排序
    sorted_lots = sorted(lots, key=lambda x: x['process_time'])
    
    schedule = []
    current_time = 0
    for lot in sorted_lots:
        start_time = max(current_time, lot['arrival_time'])
        end_time = start_time + lot['process_time']
        schedule.append({
            'lot_id': lot['lot_id'],
            'start': start_time,
            'end': end_time
        })
        current_time = end_time
    return schedule

注意:SPT有一个致命缺陷——它会无限期推迟长加工时间的lot。我在一个12寸晶圆厂遇到过这种情况:某个需要6小时刻蚀的lot被连续跳过了3天,最后变成了紧急插单。所以实际应用中,我建议给每个lot设置一个「最大等待时间」,超过这个时间就强制提升优先级。

4.3 最早交货期(EDD)——客户至上

EDD规则,按交货期排序,最早到期的先做。这个规则在半导体后道封装测试环节特别重要,因为客户对交期非常敏感。

原理:比较每个lot的承诺交货日期(Due Date),最早的优先。

适用场景

  • 客户有严格交期要求
  • 产品价值高,延迟成本大
  • 产能相对充裕

核心公式:优先级 = DueDate(lot) ,值越小优先级越高。

代码实现

def edd_schedule(lots, machine):
    # 按交货期排序
    sorted_lots = sorted(lots, key=lambda x: x['due_date'])
    
    schedule = []
    current_time = 0
    for lot in sorted_lots:
        start_time = max(current_time, lot['arrival_time'])
        end_time = start_time + lot['process_time']
        schedule.append({
            'lot_id': lot['lot_id'],
            'start': start_time,
            'end': end_time
        })
        current_time = end_time
    return schedule

个人经验:EDD规则有个坑——如果某个lot的交货期已经过了,它的优先级会变得极高,导致其他lot被严重挤压。我曾经在项目中加了一个「松弛度」参数:松弛度 = DueDate - CurrentTime - RemainingProcessTime。松弛度越小,优先级越高。这样既考虑了交期,又兼顾了剩余加工时间。

4.4 三种规则的对比与选择

这三种规则各有优劣,我整理了一个对比表,方便大家在实际项目中快速决策:

规则 优化目标 优点 缺点 适用场景
FIFO 公平性 实现简单,WIP均匀 不考虑效率 瓶颈设备、均匀负载
SPT 最小化平均流程时间 产出高,设备利用率好 长任务被饿死 工艺时间差异大
EDD 最小化最大延迟 客户满意度高 可能牺牲效率 交期敏感场景

4.5 核心逻辑流程图

下面我用一张SVG图来展示这三种规则的核心决策逻辑。你想想看,其实它们都是在做同一件事——给每个lot算一个优先级分数,然后排序。只是算分的方式不同。

规则驱动型排产核心逻辑 Lot队列输入 选择排产规则 FIFO 按到达时间排序 最早到达优先 SPT 按加工时间排序 最短时间优先 EDD 按交货期排序 最早到期优先 生成排产序列 设备执行

4.6 实际项目中的组合策略

说实话,在真实的半导体工厂里,很少只用单一规则。我参与过的项目里,最常用的策略是混合规则

  1. FIFO + SPT:先按FIFO排队,但如果某个lot的加工时间超过阈值,就按SPT重新排序。这样既保证了公平,又提高了效率。
  2. EDD + SPT:先按EDD筛选出紧急lot,再在紧急lot内部按SPT排序。这样既保交期,又保产出。
  3. 动态权重:给每个规则分配一个权重,根据当前工厂状态动态调整。比如WIP高时加大SPT权重,交期紧张时加大EDD权重。

核心要点:规则驱动型排产的精髓不在于规则本身,而在于如何组合、如何调参。我见过太多工程师把FIFO、SPT、EDD背得滚瓜烂熟,但一到现场就不知道怎么用了。记住:规则是死的,工厂是活的。

好了,这一章就到这里。这三种规则虽然简单,但它们是所有复杂排产算法的基础。下一章我们会继续深入,看看如何用加权规则和优先级矩阵来解决更复杂的排产问题。


公众号:蓝海资料掘金营,微信deep3321