【问题标题】:How to minimize setup cost in linear programming model using R如何使用 R 最小化线性规划模型中的设置成本
【发布时间】:2015-09-17 16:56:12
【问题描述】:

假设我们有一个矩阵 m:

> m
   C1 C2
M1 70 80
M2 50 61
M3 45 40

使用机器 M1-M3 和客户 C1-C2。这些值表示每台机器可以为特定客户生产的产品量,例如如果使用 M1,它将为 C1 生成 70 个项目,为 C2 生成 80 个项目。

我想使用以下约束条件,仅最小化满足需求所需的所有机器的设置成本:

每位客户的需求 >= 120;每台机器的设置成本 = 如果用于任何客户,则为 1,否则为 0。

对于这个简单的示例,解决方案是使用机器 M1 和 M2(为 C1 生产 120 个,为 C2 生产 141 个),导致总设置成本为 2。唯一可行的选择是使用机器 M1、M2 和M3,但这会导致设置成本为 3,因此不是最优的。

如何使用 R 来解决这个问题?我查看了一些使用lpSolve 的示例,但我很难对设置成本进行建模,以便它们在机器产生任何东西时为 1,否则为 0。

【问题讨论】:

    标签: r optimization linear-programming


    【解决方案1】:

    诀窍是为每台机器的设置成本创建一个二进制变量。 (它是一个指示变量。)

    英文

    如果机器 2 产生任何东西,那么二进制变量 setup_2 = 1

    如果机器 2 不产生任何结果,则 setup_2 = 0

    每台机器都需要一个这样的二进制变量。

    设置约束(公式)

    设 BigM 是一个大数。 设X_mj 为机器 m 为客户 j 执行的作业数。

    Sum(over all jobs) X_machine_job - BigM * setup_machine <= 0
    

    如果任何 X_mj 变量不为零,则强制 setup_machine 变量变为 1,这正是我们想要的。

    这是唯一的技巧。其余的配方是常规的。 这是您使用lpSolveAPI.的完整示例

    R 代码

    (代码未优化。写得更容易理解。)

    library(lpSolveAPI)
    lpAssign <- make.lp(ncol=9) #3 columns for SETUP variable (Binary) + 6 columns: 3 machines * 2 customers
    #The first 3 columns are the setup variables (binary)
    set.type(lpAssign, c(1,2,3), "binary")
    add.constraint(lpAssign, c(1,1,1), type=">=", rhs=120, indices=c(4,6,8)) #meet demand for customer 1
    add.constraint(lpAssign, c(1,1,1), type=">=", rhs=120, indices=c(5,7,9))
    
    #capacity constraints (6 of them)
    add.constraint(lpAssign, 1, type="<=", rhs=70, indices=c(4))
    add.constraint(lpAssign, 1, type="<=", rhs=80, indices=c(5))
    add.constraint(lpAssign, 1, type="<=", rhs=50, indices=c(6))
    add.constraint(lpAssign, 1, type="<=", rhs=61, indices=c(7))
    add.constraint(lpAssign, 1, type="<=", rhs=45, indices=c(8))
    add.constraint(lpAssign, 1, type="<=", rhs=40, indices=c(9))
    
    #setup cost variable constraint for each machine 
    BigM <- 1e6
    add.constraint(lpAssign, c(-1*BigM,1,1), type="<=", rhs=0, indices=c(1,4,5))
    add.constraint(lpAssign, c(-1*BigM,1,1), type="<=", rhs=0, indices=c(2,6,7))
    add.constraint(lpAssign, c(-1*BigM,1,1), type="<=", rhs=0, indices=c(3,8,9))
    
    set.objfn(lpAssign, c(1,1,1,0,0,0,0,0,0)) #All we care about is SET UP cost minimization
    
    write.lp(lpAssign, "MinSetupLp.lp", "lp")#write it out
    

    验证

    > solve(lpAssign)
    [1] 0
    > sol <- get.variables(lpAssign)
    > sol
    [1]  1  1  0 70 80 50 40  0  0
    > get.objective(lpAssign)
    [1] 2
    

    【讨论】:

    • 出于好奇,您发布的第一行代码是做什么的?我不是一个 R 忍者,但我从未见过类似的东西——一个函数调用,其中有一个带空格的参数,后跟一个表达式,全部评估为布尔值?还是说是伪代码?
    • @Paul 我认为这更接近数学表达式,但可以很容易地将其解释为伪代码。我真的不认为它打算成为 R 代码。
    【解决方案2】:

    阅读MOSEK modeling manualhttp://docs.mosek.com/generic/modeling-letter.pdf 的第 6 章,特别是第 6.2 节和其中的示例 6.1。这准确地告诉您如何使用二进制变量来模拟您的情况。然后在 lpsolve 中实现该方法,它允许您需要的二进制变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2019-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-26
      相关资源
      最近更新 更多