You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:18:32