【问题标题】:Optimization with minimum order quantities using R使用 R 优化最小订单数量
【发布时间】:2012-09-20 09:54:15
【问题描述】:

我是优化新手,我需要在一个简单的场景中实现它:

有一家汽车制造商可以生产 5 种车型的轿车/货车。与可以生产的每种型号相关的是所需的工时数和所需的钢材吨数,以及从销售一辆此类汽车/货车中获得的利润。制造商目前拥有固定数量的钢材和劳动力,应该以优化总利润的方式使用。

这是我最感兴趣的部分 - 每辆车也有最低订购量。公司必须在生产/销售该型号在经济上可行之前制造一定数量的每种型号。如果不是最终条件,这将很容易发送到optim(),因为可以为“lower = ...”参数提供一个具有最小订购数量的向量,但它不会将 0 视为选项。有人可以帮我解决这个问题,考虑到最小订单,但仍然允许订单为 0?以下是我组织相关信息/限制的方式:

Dorian <- data.frame(Model = c('SmCar', 'MdCar', 'LgCar', 'MdVan', 'LgVan'),
                   SteelReq = c(1.5,3,5,6,8), LabReq=c(30,25,40,45,55),
                   MinProd = c(1000,1000,1000,200,200),
                   Profit = c(2000,2500,3000,5500,7000))

Materials <- data.frame(Steel=6500,Labor=65000)

NetProfit<-function(x) {
  x[1]->SmCar
  x[2]->MdCar
  x[3]->LgCar
  x[4]->MdVan
  x[5]->LgVan
  np<-sum(Dorian$Profit*c(SmCar,MdCar,LgCar,MdVan,LgVan))
  np
}
LowerVec <- Dorian$MinProd #Or 0, how would I add this option?
UpperVec <- apply(rbind(Materials$Labor/Dorian$LabReq, 
                   Materials$Steel/Dorian$SteelReq),2,min)
# Attempt at using optim()
optim(c(0,0,0,0,0),NetProfit,lower=LowerVec, upper=UpperVec)

最终,我想用已知分布的随机变量替换参数,例如 Profit 和 LabReq(需要劳动力),并将其包装到一个函数中,该函数将 Steel 和 Labor 作为输入以及随机变量的参数。我将要进行多次模拟,然后在给定利润和所需劳动力的特定参数的情况下找到平均解决方案,因此理想情况下,这种优化也会很快,以便我可以执行模拟。提前感谢您的帮助!

【问题讨论】:

  • 你能不能这么好,把你的电话加到optim(),让你的例子完全reproducible
  • 在包含这个之后,我意识到我的函数NetProfit 可能不是它应该的......

标签: r mathematical-optimization


【解决方案1】:

如果您不熟悉线性规划,请从这里开始:http://en.wikipedia.org/wiki/Linear_programming

还可以查看关于混合整数编程http://en.wikipedia.org/wiki/Mixed_integer_programming#Integer_unknowns 的部分。那时您尝试求解的变量并非都是连续的,还包括布尔值或整数。


在所有方面,您的问题都是混合整数规划(准确地说,是整数规划),因为您正在尝试求解整数:为每个模型生产的车辆数量。

有已知的算法可以解决这些问题,幸运的是,它们已经为您打包到 R 包中。 Rglpk 就是其中之一,我将向您展示如何制定您的问题,以便您可以使用它的 Rglpk_solve_LP 函数。


x1, x2, x3, x4, x5 成为您要求解的变量:每个模型要生产的车辆数量。

你的目标是:

Profit = 2000 x1 + 2500 x2 + 3000 x3 + 5500 x4 + 7000 x5.

你的钢铁约束是:

1.5 x1 + 3 x2 + 5, x3 + 6 x4 + 8 x5 &lt;= 6500

您的劳动力限制是:

30 x1 + 25 x2 + 40 x3 + 45 x4 + 55 x5 &lt;= 65000

现在是最困难的部分:为最低生产要求建模。我们以第一个为例:x1 的最低生产要求要求至少生产 1000 辆汽车(x1 &gt;= 1000)或根本不生产汽车(x1 = 0)。为了对该需求建模,我们将引入一个布尔变量z1。通过布尔值,我的意思是 z1 只能取两个值:01。需求可以建模如下:

1000 z1 &lt;= x1 &lt;= 9999999 z1

为什么会这样?考虑z1 的两个可能值:

  1. 如果z1 = 0,则x1 被强制为0
  2. 如果z1 = 1x1 被强制大于1000(最低生产要求)并小于我选择的任意大数字9999999。

对每个模型重复此操作,您将不得不引入类似的布尔变量 (z2, z3, z4, z5)。最后,求解器不仅会求解x1, x2, x3, x4, x5,还会求解z1, z2, z3, z4, z5


将所有这些付诸实践,这是解决问题的代码。我们将求解向量x = (x1, x2, x3, x4, x5, z1, z2, z3, z4, z5)

library(Rglpk)

num.models <- nrow(Dorian)

# only x1, x2, x3, x4, x5 contribute to the total profit
objective  <- c(Dorian$Profit, rep(0, num.models))

constraints.mat <- rbind(
    c(Dorian$SteelReq, rep(0, num.models)),                    # total steel used
    c(Dorian$LabReq,   rep(0, num.models)),                    # total labor used
    cbind(-diag(num.models), +diag(Dorian$MinProd)),           # MinProd_i * z_i
    cbind(+diag(num.models), -diag(rep(9999999, num.models)))) # x_i - 9999999 x_i

constraints.dir <- c("<=",
                     "<=",
                     rep("<=", num.models),
                     rep("<=", num.models))

constraints.rhs <- c(Materials$Steel,
                     Materials$Labor,
                     rep(0, num.models),
                     rep(0, num.models))

var.types <- c(rep("I", num.models),  # x1, x2, x3, x4, x5 are integers
               rep("B", num.models))  # z1, z2, z3, z4, z5 are booleans

Rglpk_solve_LP(obj   = objective,
               mat   = constraints.mat,
               dir   = constraints.dir,
               rhs   = constraints.rhs,
               types = var.types,
               max   = TRUE)

# $optimum
# [1] 6408000
#
# $solution
# [1] 1000    0    0  202  471    1    0    0    1    1
#
# $status
# [1] 0

因此,最佳解决方案是为每种型号创建 (1000, 0, 0, 202, 471) 辆汽车,总利润为 6,408,000。

【讨论】:

  • 这太壮观了!我假设将这些值视为连续的并在最后将解四舍五入到最接近的整数就足够了,因为我在某处读到整数编程比单纯形算法更复杂,但当然 R 神赋予了我们使用一个使这成为非问题的软件包。然而,为了知识,将布尔变量引入诸如单纯形之类的算法是否可能/实用?
  • 你说得对,解决混合整数规划比线性规划要困难得多。但是你的问题中整数变量的数量足够小,通过 Rglpk 提供的免费求解器可以轻松解决它。
  • 单纯形法用于求解线性规划。我向您展示的技巧需要引入布尔变量,因此您的问题转移到混合整数编程,其中单纯形法(不幸的是)不能适用。我不确定有没有办法解决它。
  • 这是我写的关于最终产品的博客文章的链接:r-norberg.blogspot.com/2012/11/my-first-r-gui.html 再次感谢所有指导。我最终在计算上做的比我计划的要少,而是为它构建了一个 GUI。
猜你喜欢
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 2019-07-20
  • 2015-09-24
  • 1970-01-01
  • 2012-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多