我怎样才能使用' OR'线性程序中的陈述?

时间:2015-10-08 22:40:38

标签: r mathematical-optimization linear-programming lpsolve

我有兴趣在线性程序中构建基本上是的语句。目前我在R中使用lpSolveAPI,但我也希望得到有关此类问题的线性编程最佳实践的答案。

以下是使用lpSolveAPI包的一些工作代码:

(vector + 1 2)
(vector + 1 2)
=> #((VECTOR + 1 2) 1 2)

运行此代码并查看结果时,您会看到x6 = 0.9,x7 = -0.1和x8 = -0.2。对此的解释是购买了90%的 b ,并且出售了30%的 b

我希望建立一个约束,要求在任何地点出售 a b 时,也不能购买。 (反之亦然)

在这种特殊情况下,我认为最佳解决方案是销售20% a (x3)并购买20% b (x5或x6)。 x =(0,0,-0.2,0,0.2,0,0,0)

换句话说,如果您选择在x1和/或x2中使用非零值,则x3和x4中的值必须为0。同样,如果在x3和/或x4中选择的值不是零,则x1和x2中的值必须为零。

1 个答案:

答案 0 :(得分:3)

通常,“所有这些变量都是非负数或非正数”形式的约束要求引入一个二进制变量,指示是否已选择正面或负面情况。

我们来看前四个变量的情况;我们将引入一个二进制变量p1,指示是否处于非负方案(p1=1)或非正方案(p1=0)。现在我们有以下限制:

0 <= x1 <= 1
0 <= x2 <= 1
-0.2 <= x3 <= 0
-0.4 <= x4 <= 0

如果p1=1,则下限必须至少为0,如果p1=0则上限必须不超过0.我们可以将约束重写为:

0 <= x1 <= 1 * p1
0 <= x2 <= 1 * p1
-0.2 * (1-p1) <= x3 <= 0
-0.4 * (1-p1) <= x4 <= 0

基本上,我们需要将所有正上限乘以p1,如果我们处于非负空间则没有影响,如果我们在非负空间则将上限设置为0积极的情况。类似地,我们需要将所有负下界多个(1-p1),如果我们处于非正空间则没有影响,如果我们处于非负面情况,则将下限设置为0。

我们同样为第二组变量定义了一个新的二进制变量p2,并按如下方式更新我们的约束:

0 <= x5 <= 1 * p2
0 <= x6 <= 1 * p2
-0.1 * (1-p2) <= x7 <= 0
-0.2 * (1-p2) <= x8 <= 0

在代码中,这看起来像:

n <- nrow(mat)
LP <- make.lp(0, n+2)
set.objfn(LP, c(-mat[, 'score'], 0, 0))
set.type(LP, n+1, "binary")
set.type(LP, n+2, "binary")
set.bounds(LP, lower = c(mat[, 'lb'], 0, 0))
set.bounds(LP, upper = c(mat[, 'ub'], 1, 1))

for (i in 1:n) {
  add.constraint(LP, c(i == (1:n), (mat[i,'a'] == 1) * mat[i,'lb'], (mat[i,'b'] == 1) * mat[i,'lb']), ">=", mat[i,'lb'])
  add.constraint(LP, c(i == (1:n), -(mat[i,'a'] == 1) * mat[i,'ub'], -(mat[i,'b'] == 1) * mat[i,'ub']), "<=", 0)
}
add.constraint(LP, c(rep(1, n), 0, 0), "=", 0)

solve(LP)
get.objective(LP)
# [1] -0.058
round(head(get.variables(LP), -2), 3)
# [1]  0.0  0.0 -0.2 -0.4  0.0  0.6  0.0  0.0

找到的最优解,客观值为0.058,实际上优于OP手工找到的解(只有客观值0.03)。