我刚接触优化,我需要在一个简单的场景中实现它:
有一家汽车制造商可以生产5种型号的轿车/货车。与每一种可以生产的车型相关的是所需的大量劳动时间和所需的大量钢材,以及销售一辆这样的汽车/面包车所赚取的利润。制造商目前有固定数量的钢材和可用的劳动力,应该以优化总利润的方式使用。
这就是我所关注的部分--每辆车都有一个最小订购量。该公司必须先生产一定数量的每种型号,然后才能在经济上可行地生产/销售该型号。如果不是因为最后一个条件,这将很容易发送到optim(),因为` for = ...‘参数可以被赋予一个具有最小订单量的向量,但它不会将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)最后,我想用已知分布的随机变量替换参数,如利润和LabReq (需要劳动力),并将其封装到一个函数中,该函数将以可用的钢铁和劳动力作为输入,以及随机变量的参数。我想要多次模拟,然后在给定利润和所需劳动力的特定参数的情况下找到平均解决方案,所以理想情况下,这种优化也会很快,这样我就可以执行模拟。提前感谢您的帮助!
发布于 2012-09-20 09:54:16
如果您不熟悉线性编程,请从这里开始: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的最低生产要求要求至少生产1,000辆汽车(x1 >= 1000)或根本不生产汽车(x1 = 0)。为了对该需求进行建模,我们将引入一个布尔变量z1。通过布尔值,我的意思是z1只能接受两个值:0或1。需求可以按如下方式建模:
1000 z1 <= x1 <= 9999999 z1
为什么这是可行的?考虑z1的两个可能值
z1 = 0,则强制x1 to 0z1 = 1,然后强制x1大于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辆。
https://stackoverflow.com/questions/12499979
复制相似问题