Пакет lpsolve в R

Я использую пакет lpsolve для линейного программирования, но прочитал в его руководстве, которое решает только неотрицательные переменные.

Вот мой код:

library(lpSolve) #linear programming solver
c = c(30, 18, 20, 23, 24, 26) 
a = scan(text="66 89 82 14 35 72")
b = 50
con.qual.s1=scan(text="64 98 17 55 27 80")
con.qual.s2=scan(text="16 59 88 89 60 47")
qual.cons=c(53,82)

n=6 #activities
m=3 #resources
f.rhs = c(b,qual.cons)
f.con <- matrix (rbind(a,con.qual.s1,con.qual.s2,diag.p),nrow=m+nrow(diag.p))
f.obj.d <- c(50,53,82)
diag.d=diag(x = 1, m, m) #non-negativity
f.con.d <- matrix (rbind(t(f.con[1:m,]),diag.d),nrow=n+nrow(diag.d))
f.dir.d <- c(rep("<=",7),rep(">=",2))
f.rhs.d <- c(c,rep(0,m))
of.d=lp ("max", f.obj.d, f.con.d, f.dir.d, f.rhs.d,compute.sens=TRUE)

Обратите внимание, что игнорируется тот факт, что ограничение номер 7 неположительно.

РЕДАКТИРОВАТЬ: я добавил новый код для lpSolveAPIpackage. Чтобы проверить, что работает, я подготовил другой код для основной задачи и двойной задачи.

ДАННЫЕ:

c = c(30, 18, 20, 23, 24, 26) 
a = scan(text="66 89 82 14 35 72")
b = 50
con.qual.s1=scan(text="64 98 17 55 27 80")
con.qual.s2=scan(text="16 59 88 89 60 47")
qual.cons=c(53,82)

n=6 #activities
m=3 #resources

ОСНОВНАЯ ПРОБЛЕМА: (здесь у нас нет проблем, потому что все переменные должны быть неотрицательными)

library(lpSolveAPI)
lprec.p <- make.lp(0, n)
f.con <- matrix (rbind(a,con.qual.s1,con.qual.s2),nrow=m)

set.objfn(lprec.p, c)
add.constraint(lprec.p, f.con[1,], "<=", f.rhs[1])
for (i in 2:m) {
add.constraint(lprec.p, f.con[i,], ">=", f.rhs[i])
}

ColNames <- c("x1", "x2", "x3", "x4","x5","x6")
RowNames <- c("pi1", "pi2", "pi3")
dimnames(lprec.p) <- list(RowNames, ColNames)
lprec.p
solve(lprec.p)
get.objective(lprec.p)

ДВОЙНАЯ ПРОБЛЕМА: (здесь нам нужно, чтобы первая переменная была неположительной, поэтому используйте set.bounds)

library(lpSolveAPI)
lprec.d <- make.lp(0, m)
lp.control(lprec.d,sense="max")
f.con.d=matrix (cbind(a,con.qual.s1,con.qual.s2),ncol=m)

set.objfn(lprec.d, f.rhs)
for (i in 1:n) {
add.constraint(lprec.d, f.con.d[i,], "<=", c[i])
}
set.bounds(lprec.d, lower = c(-Inf), upper = c(0),columns = c(1))
RowNames <- c("x1", "x2", "x3", "x4","x5","x6")
ColNames <- c("pi1", "pi2", "pi3")
dimnames(lprec.d) <- list(RowNames, ColNames)
lprec.d
solve(lprec.d)
get.objective(lprec.d)

person nopeva    schedule 20.05.2013    source источник
comment
Вы можете переформулировать проблему, чтобы изложить ее в желаемой форме. Например, если переменная x не ограничена, вы можете заменить ее на x1-x2, где x1 и x2 неотрицательны.   -  person Vincent Zoonekynd    schedule 20.05.2013
comment
@ Vincent Zoonekynd благодарит меня, моя проблема в том, что x1 ограничен быть неотрицательным, а x2 и x3 ограничены быть неотрицательными. Вы знаете, как я могу это отсортировать?   -  person nopeva    schedule 20.05.2013
comment
Введите новую переменную u1 с u1=-x1. x1 исчезает (заменяется на -u1), а все остальные переменные теперь неотрицательны.   -  person Vincent Zoonekynd    schedule 20.05.2013
comment
@Vincent Zoonekynd еще раз спасибо, это хорошее решение. Однако, поскольку я работаю с основной и двойной проблемами, я хотел бы по возможности избежать изменения исходной формулировки, чтобы не запутаться и не забыть отменить изменения. Также при интерпретации чувствительности мне было бы немного сложнее. Я стараюсь избегать решателя Excel, поэтому проверяю разные пакеты.   -  person nopeva    schedule 20.05.2013
comment
Я почти уверен (каламбур), что вы сможете использовать set.bounds, см. Пример R здесь и присвоить отрицательное значение границе lower. Из документации по методу set_bounds кажется, что этого должно быть достаточно, чтобы явно установите отрицательную нижнюю границу, чтобы убедиться, что она учтена в вашей модели.   -  person Anders Gustafsson    schedule 21.05.2013
comment
Чтобы добавить к моему предыдущему комментарию, я теперь проверил, что вы действительно можете определить отрицательные нижние границы с помощью метода set.bounds. Если я правильно понимаю, вы должны включить lpSolveAPI библиотеку для доступа к этому и другим методам, описанным на странице lpsolve R. Я не знаю, как бы вы выразили границы, если бы не включали библиотеку API.   -  person Anders Gustafsson    schedule 21.05.2013
comment
@eccehomo Я добавил ответ, но после просмотра вашего обновления кода и вашего предыдущего комментария я немного запутался? Если вы пытаетесь установить неотрицательное значение pi1, почему бы вам просто не указать <= 0 в ограничении?   -  person Anders Gustafsson    schedule 21.05.2013
comment
@Anders Gustafsson Привет, благодаря тебе я нашел решение этой проблемы. Если вы отправите ответ, используя set.bounds, я приму ваше решение.   -  person nopeva    schedule 21.05.2013
comment
Рад, что у вас все получилось, @eccehomo. Ответ опубликован повторно.   -  person Anders Gustafsson    schedule 21.05.2013
comment
У меня также была проблема с необходимостью оптимизации по всем действительным числам, и я переключил пакеты R с lpsolve на lpSolveAPI. Самым большим препятствием было выяснить, что целевой вектор должен быть установлен после ограничений.   -  person mvw    schedule 16.04.2014


Ответы (1)


Если вы используете библиотеку lpSolveAPI, как это предлагается на странице lpsolve R, должно быть довольно просто применить метод set.bounds / set_bounds для назначения отрицательных границ на ваших переменных.

Например, если у вас есть три переменные x1, x2 и x3 со следующими границами:

x1 >= 0
x2 <= 0
-5 <= x3 <= 10

Используя lpSolveAPI в R и предполагая, что ваша проблема обозначена как lprec, вы можете указать это как:

set.bounds(lprec, lower = c(0, -Inf, -5), upper = c(Inf, 0, 10), columns = c(1, 2, 3))
person Anders Gustafsson    schedule 21.05.2013