0

我正在使用Rsymphony并决定使用CPLEX. 我正在研究cplexAPIR 中的内容,宁愿使用我现有的结构来构建约束矩阵。文档说 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。所以 inmat[1,1]是 中的第一个非零元素mat和 中的第一个 (0) 元素valmat[,2]第一个非零元素是 中的第三个元素 (2 ) val。在mat[,3]第一个非零元素中是 的第六 (5) 个元素,valmat[,4]第一个非零元素中是 的第八 (7) 个元素val

清如泥?我也是。

4

1 回答 1

2

我不太清楚你希望什么,但这是一种生成行号和列号的方法,该方法将使用从零开始的索引来索引该矩阵中的非零条目(尽管这对于 R 矩阵索引来说是不正常的如您所见,该规则不适用于使用 Matrix 包函数构造的稀疏矩阵。):

row(mat)[which(mat != 0)]-1
#[1] 0 1 0 1 2 0 1 0 2
col(mat)[which(mat != 0)]-1
#[1] 0 0 1 1 1 2 2 3 3
于 2017-02-01T23:38:49.713 回答