1

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

有一家汽车制造商可以生产 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 作为输入以及随机变量的参数。我将要进行多次模拟,然后在给定利润和所需劳动力的特定参数的情况下找到平均解决方案,因此理想情况下,这种优化也会很快,以便我可以执行模拟。提前感谢您的帮助!

4

1 回答 1

6

如果您不熟悉线性规划,请从这里开始: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 <= 6500

您的劳动力限制是:

30 x1 + 25 x2 + 40 x3 + 45 x4 + 55 x5 <= 65000

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

1000 z1 <= x1 <= 9999999 z1

为什么这行得通?考虑 的两个可能值z1

  1. if z1 = 0, thenx1被迫0
  2. 如果z1 = 1thenx1被迫大于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。

于 2012-09-20T01:54:15.507 回答