Преобразовать матрицу в основной формат столбца
Я использовал Rsymphony
и решил, что я хотел бы использовать CPLEX
, Я работаю через cplexAPI
в R и скорее использовал бы мою существующую структуру для построения матрицы ограничений. В документации говорится, что 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
и первый (0) элемент в val
, В mat[,2]
первый ненулевой элемент является третьим элементом (2) в val
, В mat[,3]
первый ненулевой элемент является шестым (5) элементом в val
И в mat[,4]
первый ненулевой элемент является восьмым (7) элементом val
,
Ясно как грязь? Я тоже.
1 ответ
Мне не совсем понятно, на что вы надеетесь, но вот метод для генерации номеров строк и столбцов, которые будут индексировать ненулевые записи в этой матрице с использованием индексации на основе нуля (что не является нормальным для индексации R-матрицы, хотя как вы видели, это правило не применяется к разреженным матрицам, построенным с помощью функций Matrix-package.):
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