R语言 应用lpSolveAPI

dw1jzc5e  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(145)

我有许多变量表示我可以更换的设备。当更换时,它们会改善影响指标[I]。每个变量还具有相关的年度成本节省[S]和更换成本[C]

n <- 1000 # variable count

# impact
# negative for use in minimization function
I <- -rnorm(n, mean=20000, sd=8000)
# cost savings
s <- rnorm(n, mean=2500, sd=1000)
# replacement cost
c <- rnorm(n, mean=15000, sd=5000)

字符串
我想选择更换哪些组件,以在预算范围内最大限度地发挥全面影响,同时仍确保整个项目(作为一个整体)满足一个简单的回报目标。

payback_goal <- 3
budget <- 1000000


这个问题由下面的方程描述。


的数据
我很难用lpSolveAPI来设置它。具体来说,我不知道如何合并等式3。

library(lpSolveAPI)
m <- 2 # number of constraints, disregarding binary constraint set by type
my.lp <- make.lp(m, n)
set.row(my.lp, 1, c)
# i don't think this is the correct way to set up the calculation
set.row(my.lp, 2, c/s) # cost divided by savings

# create obj fn coefficients
set.objfn(my.lp, I)
set.type(my.lp, 1:n, "binary")

eq <- c("<=", "<=")
set.constr.type(my.lp, eq)
set.rhs(my.lp, c(budget, payback_goal))

solve(my.lp)
soln1 <- get.variables(my.lp)

# total cost
s1_cost <- sum(soln1 * c)
# total impact
s1_impact <- -get.objective(my.lp)
# total simple payback
s1_pb <- sum(soln1*c) / sum(soln1*s)


我尝试了一个有点笨拙的解决方法,假设总成本将合理地接近预算,这使得第三个等式



但这只是一个近似值,我想知道如何在R代码中更准确地实现它。

yk9xbfzb

yk9xbfzb1#

你可以用你的符号线性化(3)如下:

sum([X]*[C]) - payback*sum([X]*[S]) <= 0

字符串
可以重写为:

sum([X]*([C]-payback*[S])) <= 0


只要sum([X]*[S])>0就有效。

3phpmpom

3phpmpom2#

正如@Erwin Kalvelagen所指出的那样,您可以重新制定约束以使其线性化。
但是,您应该注意到,转换是以sum([X]*[S])为条件的,这意味着

  • 如果sum([X]*[S])>0,我们应该有sum([X]*([C]-payback*[S])) <= 0
  • 如果sum([X]*[S])<0,我们应该有sum([X]*([C]-payback*[S])) >= 0

然后,将上述两种情况合并(比较并取最小值),我们可以通过sum([X]*[S])来排除影响。

代码示例(CVXR中)

set.seed(0)
n <- 1000 # variable count

# impact
# negative for use in minimization function
I <- -rnorm(n, mean = 20000, sd = 8000)
# cost savings
s <- rnorm(n, mean = 2500, sd = 1000)
# replacement cost
c <- rnorm(n, mean = 15000, sd = 5000)

library(CVXR)
X <- Variable(1, n, boolean = TRUE)
payback_goal <- 3
budget <- 1000000

obj <- Minimize(X %*% I)
# case 1: conditional on X %*% s > 0
constr1 <- list(
  X %*% c <= budget,
  X %*% (c - payback_goal * s) <= 0,
  X %*% s >= 0
)
problem1 <- Problem(obj, constr1)
sol1 <- solve(problem1)

# case 2: conditional on X %*% s < 0
constr2 <- list(
  X %*% c <= budget,
  X %*% (c - payback_goal * s) >= 0,
  X %*% s <= 0
)
problem2 <- Problem(obj, constr2)
sol2 <- solve(problem2)

# compare two cases and take the minimum between them as the solution
if (round(sol1$getValue(X)) %*% I > round(sol2$getValue(X)) %*% I) {
  sol <- sol2
} else {
  sol <- sol1
}

字符串
你会发现

> round(sol1$getValue(X)) %*% I
         [,1]
[1,] -3064996

> round(sol2$getValue(X)) %*% I
          [,1]
[1,] -287548.7


使得sol被分配有sol1

相关问题