如何用lpSolveAPI实现含投资回收期约束的设备替换规划
静态投资回收期约束的正确线性化实现
问题核心
你要解决的是带两个约束的0-1整数规划问题:
- 总替换成本不超预算
- 项目整体静态投资回收期 ≤ 目标值(总替换成本/总年节约 ≤ 回收期目标)
原代码里把回收期约束写成c/s的行向量,这是错误的——这相当于把每个设备的单独回收期相加,完全不符合整体回收期的定义。
正确约束转化
静态投资回收期的约束是非线性的:
$$\frac{\sum_{i=1}^n C_i x_i}{\sum_{i=1}^n S_i x_i} \leq P$$
其中$x_i$是0-1变量(选则为1,不选则为0),$P$是回收期目标。
要转化为线性约束,两边同时乘以总年节约(注意总年节约为正,不等号方向不变):
$$\sum_{i=1}^n C_i x_i \leq P \times \sum_{i=1}^n S_i x_i$$
整理成标准线性约束形式:
$$\sum_{i=1}^n (C_i - P \times S_i) x_i \leq 0$$
修改后的R代码
n <- 1000 # 变量数量 # 影响指标(取负是因为lpSolve默认求最小,转成最大化问题) I <- -rnorm(n, mean=20000, sd=8000) # 年成本节约 s <- rnorm(n, mean=2500, sd=1000) # 替换成本 c <- rnorm(n, mean=15000, sd=5000) payback_goal <- 3 budget <- 1000000 library(lpSolveAPI) # 现在是2个约束:预算约束 + 线性化后的回收期约束 my.lp <- make.lp(2, n) # 约束1:总替换成本 ≤ 预算 set.row(my.lp, 1, c) set.constr.type(my.lp, 1, "<=") set.rhs(my.lp, 1, budget) # 约束2:线性化后的回收期约束 Σ(Ci - P*Si)xi ≤ 0 constr_coeffs <- c - payback_goal * s set.row(my.lp, 2, constr_coeffs) set.constr.type(my.lp, 2, "<=") set.rhs(my.lp, 2, 0) # 设置目标函数(最大化总影响,所以用负的I求最小) set.objfn(my.lp, I) # 所有变量设为二元0-1变量 set.type(my.lp, 1:n, "binary") # 求解 solve(my.lp) soln1 <- get.variables(my.lp) # 计算结果 s1_cost <- sum(soln1 * c) s1_impact <- -get.objective(my.lp) s1_pb <- sum(soln1*c) / sum(soln1*s) # 输出验证 cat("总替换成本:", s1_cost, "\n") cat("总影响:", s1_impact, "\n") cat("实际回收期:", s1_pb, "\n")
注意事项
- 如果所有变量都不选,回收期会出现除以0的情况,若需要强制选至少一个设备,可以加第三个约束:$\sum x_i \geq 1$,代码里可以加一行
add.constraint(my.lp, rep(1,n), ">=", 1)。 - 确保年成本节约
s的所有值都是正数,否则线性化时不等号方向可能变化(不过实际中年节约肯定是正的)。
内容的提问来源于stack exchange,提问作者coolhand
相关产品推荐
相关产品推荐

