基于R语言实现物料需求计划(MRP)的层级需求计算问题
R语言实现多层BOM的MRP需求计算方案
核心思路
通过递归遍历BOM结构,从成品需求出发,逐层拆解每个父件对应的子件需求,累计同一物料在所有层级的需求贡献,最终得到各物料的总需求。
步骤实现
1. 预处理BOM数据
先清理无效数据(无子件的行),补充用量比例字段(示例中默认用量为1,实际替换为业务数据即可):
# 预处理后的BOM数据(移除NA子件行,补充用量qty) BOM <- data.frame( father = c("A","A","C","C"), son = c("B","C","B","D"), qty = c(1,1,1,1) # 实际业务中替换为真实用量比例 )
2. 编写递归计算函数
定义递归函数,输入父件编码、父件需求数量和当前层级,返回该父件所有子件的需求明细,同时加入循环BOM检测避免无限递归:
# 递归计算子件需求,支持循环BOM检测 calculate_mrp <- function(parent, parent_qty, current_level, processed = c()) { # 检测循环BOM,防止无限递归 if (parent %in% processed) { warning(paste("发现循环BOM:物料", parent, "已重复处理,跳过")) return(data.frame()) } processed <- c(processed, parent) # 获取当前父件的所有子件 children <- BOM[BOM$father == parent, ] # 无子女则返回空数据框 if (nrow(children) == 0) { return(data.frame()) } # 计算子件需求:父件需求 × 用量比例 children$requirement <- parent_qty * children$qty children$level <- current_level # 子件相对于成品的层级 # 递归处理每个子件,收集下一层级需求 child_requirements <- lapply(1:nrow(children), function(i) { calculate_mrp(children$son[i], children$requirement[i], current_level + 1, processed) }) # 合并当前层级与下一层级的需求数据 all_requirements <- do.call(rbind, c(list(children[, c("son", "requirement", "level")]), child_requirements)) return(all_requirements) }
3. 执行MRP计算并汇总结果
输入成品需求,调用递归函数,最后按物料编码汇总总需求:
# 成品需求示例:成品A的需求数量为10 final_demand <- data.frame(item = "A", demand = 10) # 启动MRP计算:从成品开始,子件初始层级为1 mrp_details <- calculate_mrp(final_demand$item, final_demand$demand, 1) # 汇总每个物料的总需求 total_demand <- aggregate(requirement ~ son, data = mrp_details, sum) colnames(total_demand) <- c("物料编码", "总需求数量") # 查看最终结果 print(total_demand)
结果说明
针对示例数据,成品A需求10时,各物料总需求为:
- B:10(A直接需求) + 10(C间接需求)= 20
- C:10(A直接需求)
- D:10(C直接需求)
扩展:加入提前期计算
如果需要结合提前期确定需求时间,可以将提前期数据与总需求合并,按提前期倒推需求日期:
# 提前期数据示例 lead_time <- data.frame(item = c("A","B","C","D"), lead_time = c(0,2,3,1)) # 合并总需求与提前期 total_demand_with_leadtime <- merge(total_demand, lead_time, by.x = "物料编码", by.y = "item") # 假设成品需求日期为当前日期,倒推子件需求日期 library(lubridate) total_demand_with_leadtime$需求日期 <- Sys.Date() - days(total_demand_with_leadtime$lead_time) print(total_demand_with_leadtime)
内容的提问来源于stack exchange,提问作者Nick_S
相关产品推荐
相关产品推荐

