oscar-system / Oscar.jl

A comprehensive open source computer algebra system for computations in algebra, geometry, and number theory.
https://www.oscar-system.org
Other
344 stars 126 forks source link

Save MILP to .lp file #1852

Closed ClaudiaHeYun closed 1 year ago

ClaudiaHeYun commented 1 year ago

We can create a MixedIntegerLinearProgram object in Oscar by milp = MixedIntegerLinearProgram(Polytope, objective_function; convention = :min).

If I want to save this object as a standard .lp file, currently I have to go through a rather sinuous way, i.e., by running Polymake.polytope.poly2lp(Oscar.pm_object(feasible_region(milp)),milp.polymake_milp,0,"filename.txt"). However, this line of code is not ideal. It needs to compute the feasible region of a MILP so it can be slow. And if the MILP is infeasible, this code results in an error.

I wonder whether it is possible to create a more direct way of saving LP and MILP objects as .lp files. Thanks!

@benlorenz

benlorenz commented 1 year ago

Unfortunately, while preparing some tests for my initial implementation of this I noticed that there is a bug in the polymake poly2lp function that causes a shift in the indices of the integer variables in some cases (e.g. integer_variables=[1] producing GENERAL x2 in the .lp file instead of x1). So I would prefer to delay the Oscar function until we have a fixed polymake_jll available in Oscar. The bug is fixed on the polymake master since yesterday.

micjoswig commented 1 year ago

Expect a maintenance release of polymake by next week; Oscar updates will follow in subsequent days.

ClaudiaHeYun commented 1 year ago

Thanks for adding this! However, I think I discovered a bug... When all variables are required to be integral, the save_lp function has some trouble with putting x1 in the GENERAL field. See below for a minimal example that produces this bug.

julia> P = cube(3)
A polyhedron in ambient dimension 3

julia> milp = MixedIntegerLinearProgram(P, [1,1,1])
A mixed integer linear program

julia> save_lp(stdout, milp)
MAXIMIZE
  obj: +1 x1 +1 x2 +1 x3
Subject To
  ie0: +1 x1 >= -1
  ie1: -1 x1 >= -1
  ie2: +1 x2 >= -1
  ie3: -1 x2 >= -1
  ie4: +1 x3 >= -1
  ie5: -1 x3 >= -1
BOUNDS
  x1 free
  x2 free
  x3 free
GENERAL
  x2
  x3
  ]?

If I run save_lp again, I get something different:

julia> save_lp(stdout, milp)
MAXIMIZE
  obj: +1 x1 +1 x2 +1 x3
Subject To
  ie0: +1 x1 >= -1
  ie1: -1 x1 >= -1
  ie2: +1 x2 >= -1
  ie3: -1 x2 >= -1
  ie4: +1 x3 >= -1
  ie5: -1 x3 >= -1
BOUNDS
  x1 free
  x2 free
  x3 free
GENERAL
  x2
  x3

END

It seems like every time I generate the same milp and save it, the END part is slightly different. Please take a look. Thanks!

benlorenz commented 1 year ago

That looks weird, I did work on various issues that should have fixed such errors (and this was also one of the reasons this was delayed a bit). Can you post Oscar.versioninfo(full=true) please? It should contain polymake_jll at version 400.900.000+0, if that is not the case please run using Pkg; Pkg.update().

I get the following output after a fresh install of Oscar:

julia> P = cube(3)
A polyhedron in ambient dimension 3

julia> milp = MixedIntegerLinearProgram(P, [1,1,1])
A mixed integer linear program

julia> save_lp(stdout, milp)
MAXIMIZE
  obj: +1 x1 +1 x2 +1 x3
Subject To
  ie0: +1 x1 >= -1
  ie1: -1 x1 >= -1
  ie2: +1 x2 >= -1
  ie3: -1 x2 >= -1
  ie4: +1 x3 >= -1
  ie5: -1 x3 >= -1
BOUNDS
  x1 free
  x2 free
  x3 free
GENERAL
  x1
  x2
  x3
END
ClaudiaHeYun commented 1 year ago

Ah I see! I had polymake_jll v400.700.1+1. I updated my packages and everything is good now. Thank you!!

ClaudiaHeYun commented 1 year ago

Hi! Right now save_lp produces an error if the lp or milp I'm trying to save is infeasible. I wonder if there is a way around that? I would like to use external programs to check for feasibility because they are sometimes faster than the feasibility check in Oscar. Thanks!

benlorenz commented 1 year ago

Hi! Right now save_lp produces an error if the lp or milp I'm trying to save is infeasible. I wonder if there is a way around that? I would like to use external programs to check for feasibility because they are sometimes faster than the feasibility check in Oscar. Thanks!

Unfortunately there is no quick way around this for save_lp, it seems that we missed this issue and the check is still in the corresponding polymake function. But I did remove such a check from save_mps, so can you try if mps files would work for you instead? I think most external solvers should support this format as well.