给定一个矩阵,我想找到尽可能接近某个目标向量的行的线性组合。此外,我希望行权重为非负数并求和为 1。我尝试使用 R 的 limSolve 包解决问题,但它报告了一个关于矛盾不等式的错误。这是我的函数:
library(limSolve)
find.weights <- function(target.vector, a.matrix) {
# parameters to the objective function
A <- t(a.matrix)
B <- target.vector
# equality constraint (weights sum to 1)
E <- matrix(rep(1, nrow(a.matrix)), nrow = 1)
F <- 1
# inequality constraints (all weights nonnegative)
G <- diag(1, nrow(a.matrix))
H <- rep(0, nrow(a.matrix))
lsei(A = A, B = B, E = E, F = F, G = G, H = H)
}
以下是导致问题的输入。
target.vector:
[1] 0.00 0.30 0.10 0.15 0.15 0.15 0.00 0.15 0.00
a.矩阵:
[1,] 0.0000000000 1.0000000 0.000000000 0.0000000 0.00000000 0.0000000 0.000000000 0 0
[2,] 1.0000000000 0.0000000 0.000000000 0.0000000 0.00000000 0.0000000 0.000000000 0 0
[3,] 0.0000000000 0.0000000 0.000000000 0.0000000 0.00000000 0.0000000 0.000000000 1 0
[4,] 0.0000000000 0.0000000 0.000000000 0.0000000 0.00000000 1.0000000 0.000000000 0 0
[5,] 0.0000000000 0.6318000 0.044100000 0.2241000 0.01000000 0.0900000 0.000000000 0 0
[6,] -0.0069249820 0.4961489 0.030322369 0.1164405 0.03519697 0.3167728 0.012043447 0 0
[7,] 0.0410533877 0.2434423 0.007709501 0.0292961 0.06651868 0.5986681 0.013311866 0 0
[8,] 0.0000000000 0.0000000 0.240000000 0.7600000 0.00000000 0.0000000 0.000000000 0 0
[9,] -0.0001006841 0.6229848 0.051032756 0.1945897 0.01236401 0.1112761 0.007853359 0 0
当我使用这些输入调用函数时,我收到上述错误:
> result <- find.weights(target.vector, a.matrix)
Warning message:
In lsei(A = A, B = B, E = E, F = F, G = G, H = H) :
LSEI error: inequalities contradictory
但是,如果我限制行数或列数,该功能似乎可以正常工作:
> result <- find.weights(target.vector, a.matrix[1:8,]) # OK
> result <- find.weights(target.vector[1:6], a.matrix[,1:6]) # OK
> result <- find.weights(target.vector[1:7], a.matrix[,1:7]) # NOPE
Warning message:
In lsei(A = A, B = B, E = E, F = F, G = G, H = H) :
LSEI error: inequalities contradictory
任何建议将不胜感激。
LSEI error: inequalities contradictory
当您通过 E
、F
、G
和 H
指定的线性约束定义一个不可行的问题时发生。换句话说,当没有向量x
可以同时解决所有E %*% x == F
和G %*% x >= H
约束时。例如,考虑一个问题,该问题将约束两个变量x1
和x2
,以便在x_1 >= 0
和x2 >= 0
时x1 + x2 == -1
。显然,没有x1
和x2
值可以满足所有三个约束,这个问题是不可行的。
在你的问题中,n
是要求解的变量的数量,你所要求的只是x_1
、x_2
、...、x_n
非负数,并且它们的总和为 1
。一个可行的解决方案(在无限多个假设n > 1
中(是选择x_1 = 1
并x_2 = ... = x_n = 0
。所以先验地,lsei
不应该抛出你提到的错误。事实上,您的代码在我的机器上运行良好,我无法重现您看到的错误。您是否可能遇到与您在此处发布的代码不同的错误?
事实上,lsei
给出了虚假的"不平等矛盾"。 这是一个测试用例:我的约束要求解和为 1(方程(并递减(不等式(。
n <- 12
A <- diag(1, 2, n)
B <- c(1, .5)
E <- matrix(1, 1, n)
F <- 1 # pre-set value was FALSE
G <- -diff(diag(1, n+1, n)
H <- numeric(n)
lsei(A, B, E, F, G, H)
首次运行表明该问题是可行的。 输出:
$X
[1] 0.75 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
$residualNorm
[1] 4.440892e-16
$solutionNorm
[1] 0.125
$IsError
[1] FALSE
$type
[1] "lsei"
但是后来我更改了A[1,1]
,这与约束无关:
A1 <- diag(c(1000,1),2,n) # change one element
lsei(A=A1, B, E, F, G, H)
而对于轻度病态的A1
,它失败了:
$X
[1] -2.6689062 -0.5899748 0.6479330 0.3362563 0.4279018 0.4279018
[7] 0.4279018 0.4279018 0.4279018 0.4279018 0.4279018 0.2793792
$residualNorm
[1] 3.408485
$solutionNorm
[1] 7128401
$IsError
[1] TRUE
$type
[1] "lsei"
Warning message:
In lsei(A = A1, B = B, E = E, F = F, G = G, H = H) :
LSEI error: inequalities contradictory
我认为这表明错误是虚假的,即这是一个错误。