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

为R语言MIP钢铁切割优化模型添加单库存源约束

钢铁切割优化MIP模型:修正约束并确认工件单库存下料逻辑

你需要实现的“每个工件仅从单个库存件下料”的要求,其实已经通过现有约束1的逻辑覆盖,但当前模型存在约束2的写法错误,导致无法正确限制库存件的总下料长度。以下是修正后的完整代码及说明:

核心逻辑说明

你的二进制变量steel_cut[work, inventory]表示工件work是否从库存件inventory下料,约束1sum_over(steel_cut[work, inventory], inventory = 1:invent_count) == 1直接保证了每个工件只能被分配到一个库存件(所有库存件对应的变量和为1,即只有一个库存件的变量为1),完全满足“单个工件仅从单个库存下料”的需求。

修正后的完整代码

# 加载所需包
library(dplyr)
library(ompr)
library(ompr.roi)
library(ROI)

# 定义问题数据
work_tbl <- data.frame(length = c(2500, 500, 700, 1200, 1500, 2000, 2500, 3000, 4000, 5250))
inventory_tbl <-
  data.frame(length = c(1300, 2000, 1800, 2600, 3000, 2000, 5000, 6000, 7000, 9000, 2000, 500, 4000, 12000, 7400, 13000))

# 定义变量参数
work_count <- nrow(work_tbl)
invent_count <- nrow(inventory_tbl)
# 优化big_M取值:单个库存最多能放的工件数上限,避免M值过大影响求解效率
big_M <- ceiling(max(inventory_tbl$length) / min(work_tbl$length))

# 初始化MIP模型
steel_model <- ompr::MIPModel() %>% 
  # 二进制变量:工件work是否从库存inventory下料
  add_variable(steel_cut[work, inventory],
               work = 1:work_count,
               inventory = 1:invent_count,
               type = "binary") %>% 
  # 二进制变量:是否启用该库存件
  add_variable(take_item[inventory],
               inventory = 1:invent_count,
               type = "binary") %>% 
  # 约束1:每个工件必须被下料一次(仅对应一个库存件)
  add_constraint(sum_over(steel_cut[work, inventory], inventory = 1:invent_count) == 1,
                 work = 1:work_count) %>% 
  # 约束2:每个库存件的总下料长度不能超过自身长度(修正原索引错误)
  add_constraint(sum_over(steel_cut[work, inventory] * work_tbl$length[work], work = 1:work_count) <= inventory_tbl$length[inventory],
                 inventory = 1:invent_count) %>% 
  # 约束3:只要有工件从该库存下料,take_item就必须为1
  add_constraint(sum_over(steel_cut[work, inventory], work = 1:work_count) <= big_M * take_item[inventory],
                 inventory = 1:invent_count) %>% 
  # 目标函数:最小化废料 = 启用的库存总长度 - 下料的工件总长度
  set_objective(
    sum_over(take_item[inventory] * inventory_tbl$length[inventory], inventory = 1:invent_count) - 
    sum_over(steel_cut[work, inventory] * work_tbl$length[work], work = 1:work_count, inventory = 1:invent_count), 
    sense = "min"
  )

# 查看模型结构
steel_model

# 求解模型
solution <- ompr::solve_model(steel_model, with_ROI(solver = "glpk", verbose = TRUE))  

# 查看目标值(废料长度)
solution$objective_value

# 提取求解结果
steel_model_soln <-
  ompr::get_solution(solution, steel_cut[work, inventory]) %>% 
  filter(value > 0) %>% 
  mutate(
    工件长度 = work_tbl$length[work],
    库存件长度 = inventory_tbl$length[inventory]
  )

# 查看结果
steel_model_soln

关键修正点

  1. 修复约束2的索引错误:原代码同时指定inventory和work索引,生成了大量冗余约束;修正后仅针对每个库存件生成一个总长度约束,符合实际逻辑。
  2. 优化big_M取值:改用最大库存长度除以最小工件长度的向上取整值,避免过大的M值降低求解效率。
  3. 增强结果可读性:在输出结果中添加工件和库存件的实际长度,方便直观查看下料分配情况。

内容的提问来源于stack exchange,提问作者RegressionSquirrel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:37:15