【发布时间】:2017-06-18 20:36:52
【问题描述】:
我正在使用Rsymphony,并决定使用CPLEX。我正在研究 R 中的cplexAPI,宁愿使用我现有的结构来构建约束矩阵。文档说 API 采用列主要顺序格式的约束矩阵,只有非零元素。所以我需要一种方法来(我希望优雅地)将矩阵转换为这种形式。
例如:
3.2 创建和求解混合整数规划 (MIP) 问题 下面,将创建和求解一个示例 MIP: ...
受制于:
目前,这是作为矩阵实现的
> mat = matrix(c(-1, 1, 1, 10,
+ 1, -3, 1, 0,
+ 0, 1, 0, -3.5),byrow = TRUE, nrow=3,ncol=4)
> mat
[,1] [,2] [,3] [,4]
[1,] -1 1 1 10.0
[2,] 1 -3 1 0.0
[3,] 0 1 0 -3.5
从文档中,我需要以下元素。
约束矩阵以列主要顺序格式传递。这里要小心:所有索引都从 0 开始!开始行索引。
beg <- c(0, 2, 5, 7)
您会注意到,从左上角向下工作就是这种工作方式。在第一个位置 (0),第二列从第三个非零元素开始,第三列从第五个元素开始,依此类推。
每行非零元素的数量。
cnt <- c(2, 3, 2, 2)
同样,我会说的是列。
列索引。
ind <- c(0, 1, 0, 1, 2, 0, 1, 0, 2)
这是每个非零元素的列索引。
非零元素。
val <- c(-1.0, 1.0, 1.0, -3.0, 1.0, 1.0, 1.0, 10.0, -3.5)
我很难找到完成这项工作的方法。
我知道我可以通过以下方式轻松创建val:
c(mat)
[1] -1.0 1.0 0.0 1.0 -3.0 1.0 1.0 1.0 0.0 10.0 0.0 -3.5
val2 <- mat[mat !=0]
val <- c(-1.0, 1.0, 1.0, -3.0, 1.0, 1.0, 1.0, 10.0, -3.5)
val2 & val
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
我可以通过以下方式轻松创建cnt:
cnt <- apply(mat,2,function(x) Matrix::nnzero(x, na.counted = NA))
cnt
[1] 2 3 2 2
感谢@42-
ind2 <- row(mat)[which(mat != 0)]-1
ind <- c(0, 1, 0, 1, 2, 0, 1, 0, 2)
ind2 == ind
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
现在是beg。
重述片段,
mat
[,1] [,2] [,3] [,4]
[1,] -1 1 1 10.0
[2,] 1 -3 1 0.0
[3,] 0 1 0 -3.5
beg <- c(0, 2, 5, 7)
val <- c(-1.0, 1.0, 1.0, -3.0, 1.0, 1.0, 1.0, 10.0, -3.5)
beg 是一个沿着val 中非零元素位置计数的索引。所以mat[1,1] 是mat 中的第一个非零元素和val 中的第一个 (0) 元素。在mat[,2] 中,第一个非零元素是val 中的第三个元素 (2)。在 mat[,3] 中,第一个非零元素是 val 中的第六 (5) 个元素,在 mat[,4] 中,第一个非零元素是 val 中的第八 (7) 个元素。
一清二楚?我也是。
【问题讨论】:
标签: r matrix column-major-order