R: ompr пакетные ограничения
Я использую пакет ompr в R, чтобы решить проблему omptimization. Письменная проблема оптимизации выглядит следующим образом:
Мин wi * xi
xi ϵ {0,1}
xi ≤ xj, j последователь i
i является последователем j, если в матрице расстояний (distmatrix) доступно значение. Если значение равно inf, соединение от i до j невозможно
Цель состоит в том, чтобы проанализировать спецификацию, чтобы немного облегчить мой пример. Я создал более простой пример с меньшим количеством материалов.
vertices_undef <- data.frame(matrix(ncol=3, nrow=5))
vertices_undef$X1 <- c("3","5","9","7","2")
vertices_undef$X3 <- c(12, -8, 8, 3, -9)
rownames(vertices_undef) <- vertices_undef$X1
distMatrix <- data.frame(matrix(ncol=5, nrow=5))
rownames(distMatrix) <- vertices_undef$X1
colnames(distMatrix) <- vertices_undef$X1
distMatrix$`3` <- c("inf", 0.7, "inf", "inf", 0.3)
distMatrix$`5` <- c(3, "inf", "inf", "inf", 0.3)
distMatrix$`9` <- c("inf", 0.7, "inf", 0, 3)
distMatrix$`7` <- c("inf", "inf", "inf", 0.3, "inf")
distMatrix$`2` <- c("inf", 7, "inf", "inf", 0.3)
w <- vertices_undef$X3
w <- t(w)
colnames(w)<- vertices_undef$ID
w <- t(w)
result <- MIPModel() %>%
add_variable(x[i], type = "binary", i = as.integer(as.character(vertices_undef$X1))) %>%
set_objective(sum_expr(x[i]*w[i,1], i = as.integer(as.character(vertices_undef$X1))), "min") %>%
add_constraint(x[i]<=x[j], i = as.integer(as.character(vertices_undef$X1)), j = as.integer(as.character(vertices_undef$X1)), is.finite(distMatrix[i,j])==TRUE)%>%
solve_model(with_ROI(solver = "glpk"))
get_solution(result, x[i])
Если я вычеркну ограничение, я получу результат, который я бы объяснил (считая, что ограничение не используется). Как я могу обратиться в пределах ограничений i и j отдельно?
1 ответ
Состояние фильтра в вашем add_constraint
вызов выдает ошибку. i
а также j
являются векторами, и индексирование матрицы с использованием векторов не создает единого логического вектора, как того требует add_constraint
, но другая матрица. Кроме того, некоторые i/j
комбинации не являются частью вашего distMatrix
матрица.
То, что происходит внутри, по существу таково:
x <- expand.grid(i = as.integer(as.character(vertices_undef$X1)),
j = as.integer(as.character(vertices_undef$X1)))
is.finite(distMatrix[x$i, x$j])
Условие фильтра (т.е. выражение is.finite(distMatrix[i,j])==TRUE
) должен вернуть логический вектор с длиной i/j
это указывает, какая строка должна быть включена в модель, а какая не должна быть включена.