Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unbounded LPs reported as Infeasible #248

Open
prof-anderson opened this issue Jan 18, 2019 · 11 comments
Open

Unbounded LPs reported as Infeasible #248

prof-anderson opened this issue Jan 18, 2019 · 11 comments

Comments

@prof-anderson
Copy link

Here is a simple two variable problem that returns a status of infeasible when it should be unbounded. I tested this three solver (glpk, lpsolve, and symphony). All packages are up to date from CRAN.

library (ROI, quietly = TRUE)      
library (ROI.plugin.glpk, quietly = TRUE) 
library (ompr, quietly = TRUE)   
library (ompr.roi, quietly = TRUE)
library (magrittr)

model_unbounded <- MIPModel() %>%
  add_variable(x, type = "continuous", lb = 0) %>%
  add_variable(y, type = "continuous",lb = 0) %>%

  set_objective(x+y, "max") %>%
  
  add_constraint(x+y >= 2000) #fabrication

result_unbounded <-  solve_model(model_infeas, with_ROI(solver = "glpk"))
print(solver_status(result_unbounded))

library (ROI.plugin.symphony, quietly = TRUE) # Plugin for solving

result_unbounded <-  solve_model(model_infeas, with_ROI(solver = "glpk"))
print(solver_status(result_unbounded))

library (ROI.plugin.lpsolve, quietly = TRUE) # Plugin for solving

result_unbounded <-  solve_model(model_infeas, with_ROI(solver = "glpk"))
print(solver_status(result_unbounded))
@prof-anderson
Copy link
Author

Minor correction to last two solves but it does still return
[1] "infeasible"
for all three solvers. (This is a minimal code example from a larger case where I ran into the problem.)

`library (ROI, quietly = TRUE) # R Optimization Interface
library (ROI.plugin.glpk, quietly = TRUE) # Plugin for solving
library (ompr, quietly = TRUE) # Allows specifying model algebraically
library (ompr.roi, quietly = TRUE) # Glue for ompr to solve with ROI
library (magrittr)

model_unbounded <- MIPModel() %>%
add_variable(x, type = "continuous", lb = 0) %>%
add_variable(y, type = "continuous",lb = 0) %>%

set_objective(x+y, "max") %>%

add_constraint(x+y >= 2000) #fabrication

result_unbounded <- solve_model(model_infeas, with_ROI(solver = "glpk"))
print(solver_status(result_unbounded))

library (ROI.plugin.symphony, quietly = TRUE) # Plugin for solving

result_unbounded <- solve_model(model_infeas, with_ROI(solver = "symphony"))
print(solver_status(result_unbounded))

library (ROI.plugin.lpsolve, quietly = TRUE) # Plugin for solving

result_unbounded <- solve_model(model_infeas, with_ROI(solver = "lpsolve"))
print(solver_status(result_unbounded))
`

@dirkdegel
Copy link

Hi prof-anderson,

I'm not 100% sure but you solve the "model_infeas" in the solve statement, which is not defined in the code you are providing. I assume it was used before and is still in memory. If you are using "solve_model(model_unbounded , with_ROI(solver = "glpk"))" it should be fine.

@prof-anderson
Copy link
Author

Good spot. I had typos from trying to simplify and come up with a short example. Thanks.

I fixed the typos and it is still returning infeasible rather than unbounded.

library (ROI, quietly = TRUE)      # R Optimization Interface
library (ROI.plugin.glpk, quietly = TRUE) # Plugin for solving
library (ompr, quietly = TRUE)     # Allows specifying model algebraically
library (ompr.roi, quietly = TRUE) # Glue for ompr to solve with ROI
library (magrittr)

model_unbounded <- MIPModel() %>%
  add_variable(x, type = "continuous", lb = 0) %>%
  add_variable(y, type = "continuous",lb = 0) %>%

  set_objective(x+y, "max") %>%
  
  add_constraint(x+y >= 2000) #fabrication

result_unbounded <-  solve_model(model_unbounded, with_ROI(solver = "glpk"))
print(solver_status(result_unbounded))

library (ROI.plugin.symphony, quietly = TRUE) # Plugin for solving

result_unbounded <-  solve_model(model_unbounded, with_ROI(solver = "symphony"))
print(solver_status(result_unbounded))

library (ROI.plugin.lpsolve, quietly = TRUE) # Plugin for solving

result_unbounded <-  solve_model(model_unbounded, with_ROI(solver = "lpsolve"))
print(solver_status(result_unbounded))

@hugolarzabal
Copy link
Contributor

hugolarzabal commented Jan 25, 2019

Hello
What version of ompr are you using ?
When I try your example, the status is "unbounded" with every solver.

Edit:
I think your problem is related with that post in ompr.ROI
dirkschumacher/ompr.roi#17
I am currently using the pull request versions of ompr and ompr.ROI used by rickyars after he noticed those problems so I see the true status from the solver:

$code
[1] 1

$msg
solver symphony
code 237
symbol TM_UNBOUNDED
message TM_UNBOUNDED
roi_code 1

the current version of ompr.roi only use two status "optimal" and "infeasible" which actually mean "success" and "failure" and are the direct translation of code = 0 or code = 1.

Edit2: If you want to use the pull request version of rickyars, you may need to merge it manually with ompr master first since it is not based on the most recent version of ompr.

@sbmack
Copy link

sbmack commented Jan 25, 2019

Re: Dirk:

Edit2: If you want to use the pull request version of rickyars, you may need to merge it manually with ompr master first since it is not based on the most recent version of ompr.

Do you have instructions for how to do that?

Thanks,

SteveM

@hugolarzabal
Copy link
Contributor

You have to create a new branch of the project from rickyars pull request in your own repository in github and then merge it with the master.

I made it myself a few months ago, it is not really dificult but I don't remember the exact steps.

@prof-anderson
Copy link
Author

Thanks. I thought I was going a little crazy. That seems like it is the exact source of the problem.

I am using 0.8.0 from CRAN. Using an unreleased version isn't really an option for me since I have students using a mix of platforms (PC, Mac, RStudio.cloud) and R proficiency.

If the issue is interpretation of the 0 status, a quick and dirty hack would be to change the returned message from "Infeasible" to "Infeasible/Unbounded" or "No Optimal Solution Found" and let the analyst infer the situation.

A more full fix could then be incorporated later, perhaps using part of the fork mentioned above.

Thanks again!

@dirkschumacher
Copy link
Owner

Is this an immediate need for an ongoing course? I will try to work on this and the PR's of @rickyars next.

@hugolarzabal
Copy link
Contributor

If the issue is interpretation of the 0 status, a quick and dirty hack would be to change the returned message from "Infeasible" to "Infeasible/Unbounded" or "No Optimal Solution Found" and let the analyst infer the situation.

Yes, it is exactly that.
The meaning of 0 and 1 thought may differ slightly between solver:

  • Optimal or optimal within gap tolerance is always 0
  • Infeasible or unbounded are always 1
  • Some status in between like "stopped on time limit" may be 1 or 0 depending on the solver (often without diferencing the case where a feasible solution has been found or not)

Also solvers have verbosity options and print their results. It is hard to recover this information to use in a script but you can at least see it on your screen.

@dirkschumacher
Copy link
Owner

ROI's status code is documented to be the following:

The status code is 0 on success (no error occurred) 1 otherwise.

So what we could do is add another status code called success and let ompr.roi return success if code = 0 and error if code = 1.

@dirkschumacher
Copy link
Owner

We should probably do two things in the future:

  • See if we can have more status codes in ROI
  • Differentiate between a solution status (feasible, no-solution, etc.?) and a termination status (success, error, infeasible, userlimit, optimal, feasible, etc.?)

A recent addition to ompr.roi now also returns the full solver specific message/status. So that can be used as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants