通过线性限制优化解决方案

时间:2015-07-27 18:00:55

标签: r mathematical-optimization

我们说我有一个带有 N 变量的线性系统,但我只有 N-1 等式(约束)。如何使用R?

获得每个N变量的可行集(范围)

示例:

A <- matrix(data=c(0,1,0,1,0,1,0,1,
                   0,0,1,1,0,0,1,1,
                   0,0,0,0,1,1,1,1,
                   0,0,0,1,0,0,0,1,
                   0,0,0,0,0,1,0,1,
                   0,0,0,0,0,0,1,1,
                   1,1,1,1,1,1,1,1
                   ),
            ncol=8, byrow=T)
b <- matrix(data=c(0.2,0.4,0.6,0.06,0.18,0.12,1),
            ncol=1)
> A
##     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
##[1,]    0    1    0    1    0    1    0    1
##[2,]    0    0    1    1    0    0    1    1
##[3,]    0    0    0    0    1    1    1    1
##[4,]    0    0    0    1    0    0    0    1
##[5,]    0    0    0    0    0    1    0    1
##[6,]    0    0    0    0    0    0    1    1
##[7,]    1    1    1    1    1    1    1    1
> b
##     [,1]
##[1,] 0.20
##[2,] 0.40
##[3,] 0.60
##[4,] 0.06
##[5,] 0.18
##[6,] 0.12
##[7,] 1.00

附加约束:每个值都必须是正确的,并且应该在0和1之间(最后一个值可以省略,因为最后一个等式加起来只有正确的值)

3 个答案:

答案 0 :(得分:2)

您所描述的问题最好通过线性编程来解决,因为您有一组线性约束(Ax = b,x> = 0,x <= 1)和线性目标(最大化或最小化)一些x_i)。鉴于程序的简单结构,我将使用R:

中的lpSolve包来解决它
library(lpSolve)
for (idx in seq_len(ncol(A))) {
  for (type in c("min", "max")) {
    mod <- lp(direction = type,
              objective.in = as.numeric(seq_len(ncol(A)) == idx),
              const.mat = rbind(A, diag(ncol(A))),
              const.dir = c(rep("=", length(b)), rep("<=", ncol(A))),
              const.rhs = c(b, rep(1, ncol(A))))
    print(paste("Variable:", idx, "type:", type, "value", mod$objval))
  }
}
# [1] "Variable: 1 type: min value 0.1"
# [1] "Variable: 1 type: max value 0.12"
# [1] "Variable: 2 type: min value 0"
# [1] "Variable: 2 type: max value 0.02"
# [1] "Variable: 3 type: min value 0.26"
# [1] "Variable: 3 type: max value 0.28"
# [1] "Variable: 4 type: min value 0"
# [1] "Variable: 4 type: max value 0.02"
# [1] "Variable: 5 type: min value 0.34"
# [1] "Variable: 5 type: max value 0.36"
# [1] "Variable: 6 type: min value 0.12"
# [1] "Variable: 6 type: max value 0.14"
# [1] "Variable: 7 type: min value 0.06"
# [1] "Variable: 7 type: max value 0.08"
# [1] "Variable: 8 type: min value 0.04"
# [1] "Variable: 8 type: max value 0.06"

答案 1 :(得分:1)

我建议使用方法作为正则化回归。 R中有一些包,例如larsglmnet。我建议你阅读answer

基本上,在R你会运行

library(lars)
model=lars(A,b)
coef(model)
      [,1] [,2]  [,3] [,4]   [,5]   [,6]    [,7] [,8]
[1,] 0.000 0.00 0.000    0 0.0000 0.0000 0.00000    0
[2,] 0.000 0.00 0.000    0 0.0982 0.0000 0.00000    0
[3,] 0.131 0.00 0.000    0 0.2000 0.0000 0.00000    0
[4,] 0.138 0.00 0.185    0 0.3849 0.0000 0.00000    0
[5,] 0.109 0.00 0.260    0 0.4000 0.0600 0.00000    0
[6,] 0.109 0.00 0.260    0 0.3997 0.0603 0.00029    0
[7,] 0.100 0.02 0.280    0 0.3600 0.1200 0.06000    0

结果是一个7x8矩阵,其中从上到下的每一行中最重要的变量都输入到模型中。例如,第一行尝试仅使用截距拟合模型。第二个引入了8的最强变量,即第5个,依此类推。从结果中可以看出变量4和8一直具有零系数,表示它们对于所有其他变量都不重要。

答案 2 :(得分:1)

您需要计算“空格”&#39; A,例如在 pracma 中包 MASS 或函数nullspace()。首先计算最小二乘解,然后在零空间中添加向量的线性组合:

library(pracma)
N <- nullspace(A)
# 0.3535534 * c(-1, 1, 1, -1, 1, -1, 1, -1)
x0 <- qr.solve(A, b)
# [1]  0.16 -0.04  0.22  0.06  0.30  0.18  0.12  0.00

和x0 + x * N,x real,生成所有可能的解决方案。

此示例中的N是1-dim。,因为A的等级为1.使用更少的等式,零空间将具有更多维度。

相关问题