4

I'm using lpsolve package for linear programming but have read in its tutorial that only solves for non-negative variables.

Here's my code:

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)

Note that ignores the fact that constraint number 7 is non-positive.

EDIT: I have added new code for the lpSolveAPIpackage. In order to check that works I have prepared different code for the primal problem and the dual problem.

THE DATA:

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

PRIMAL PROBLEM: (here we don't have any problem because all variables must be non-negative)

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)

DUAL PROBLEM: (here we need the first variable to be non-positive so use 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)
nopeva
  • 1,583
  • 5
  • 22
  • 38
  • You can reformulate your problem to put it in the desired form. For instance, if a variable `x` is unconstrained, you can replace it with `x1-x2` where `x1` and `x2` are both non-negative. – Vincent Zoonekynd May 20 '13 at 15:08
  • @ Vincent Zoonekynd thanks my problem is that x1 is constrained to be non-positive while x2 and x3 are constrained to be non-negative. Do you know how could I sort this? – nopeva May 20 '13 at 15:19
  • 1
    Introduce a new variable, `u1`, with `u1=-x1`. `x1` disappears (it is replaced by `-u1`), and all the remaining variables are now non-negative. – Vincent Zoonekynd May 20 '13 at 15:46
  • @Vincent Zoonekynd thanks again that's a good solution. However, since I'm working with the primal and the dual problems I would like to avoid changing the original formulation if possible so I don't get confused or forget to reverse the changes. Also when interpreting the sensitivities everything would be a bit more difficult for me. I'm trying to avoid excel's solver so I'm checking the different packages. – nopeva May 20 '13 at 16:10
  • 2
    I am almost positive (pun intended) that you should be able to use `set.bounds`, see R example [here](http://lpsolve.sourceforge.net/5.5/R.htm) and assign a negative value to the `lower` bound. From the documentation for the [set_bounds](http://lpsolve.sourceforge.net/5.5/set_bounds.htm) method, it does seem like it should be enough to explicitly set a negative lower bound to ensure that it is accounted for in your model. – Anders Gustafsson May 20 '13 at 20:02
  • 1
    To add to my previous comment, I have now verified that you can indeed define negative lower bounds with the `set.bounds` method. If I understand correctly, you should include the `lpSolveAPI` library to access this and other methods that are described on the *lpsolve R* page. I do not know how you would express the bounds if you don't include the API library. – Anders Gustafsson May 21 '13 at 11:04
  • @eccehomo I added an answer but after looking at your code update and your previous comment I am a little confused? If it is `pi1` you are trying to set to a non-negative value, why don't you just specify `<= 0` in the constraint? – Anders Gustafsson May 21 '13 at 13:32
  • @Anders Gustafsson Hi, thanks to you I found the solution to this. If you post the answer using `set.bounds` I will accept your solution. – nopeva May 21 '13 at 14:19
  • Glad that things worked out for you, @eccehomo. Answer re-posted. – Anders Gustafsson May 21 '13 at 15:19
  • I also had problem needing optimization over all real numbers and switched R packages from lpsolve to lpSolveAPI. Biggest hurdle was to find out that the objective vector must be set after the constraints. – mvw Apr 16 '14 at 10:11

1 Answers1

6

If you use the lpSolveAPI library as is proposed on the lpsolve R page, it should be fairly straightforward to apply the set.bounds/set_bounds method to assign negative bounds on your variables.

For example, if you have three variables x1, x2 and x3 with the following bounds:

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

With the lpSolveAPI in R, and assuming that your problem is denoted lprec, you should be able to specify this as:

set.bounds(lprec, lower = c(0, -Inf, -5), upper = c(Inf, 0, 10), columns = c(1, 2, 3))
Anders Gustafsson
  • 15,837
  • 8
  • 56
  • 114