jyp / glpk-hs

Haskell bindings to glpk
Other
13 stars 18 forks source link

reading textual glpsol output? #6

Open jwaldmann opened 6 years ago

jwaldmann commented 6 years ago

glpk/doc/glpk.pdf Chapter 2 Section 2.1.3 "The standard version of GLPK API is not thread safe" - so we cannot have concurrent API calls in glpk-hs. Or can we? (I am getting segfaults when I try.)

A work-around is to call glpksol as an external process (then we could have many of them). For this, input and output need to be textual (via tempfiles or pipes).

There is Data.LinearProgram.GLPK.IO.writeLP, but where is the function to parse the solver's output?

jyp commented 6 years ago

As far as I know there is no code to make glpk thread-safe in glpk-hs.

I don't think there is any parsing going on, rather the results are obtained using the FFI.

jwaldmann commented 6 years ago

How hard would it be to add a parser? I have trouble understanding the output format of glpsol (and I don't find its specification). In this example

result/bin/glpk-hs-example
0: obj =  -0.000000000e+00 inf =   0.000e+00 (3)
3: obj =   7.000000000e+02 inf =   0.000e+00 (0)
3: mip =     not found yet <=              +inf        (1; 0)
3: >>>>>   7.000000000e+02 <=   7.000000000e+02   0.0% (1; 0)
3: mip =   7.000000000e+02 <=     tree is empty   0.0% (0; 1)
(Success,Just (700.0,fromList [("x1",40.0),("x2",50.0),("x3",0.0)]))

I see that 700.0 is in the line marked >>>>> but where do 40.0 and 50.0 come from?

EDIT

it works with

 glpsol --lp /tmp/lp.lp -w /dev/stdout

which gives

 c Problem:    
c Rows:       3
c Columns:    3
c Non-zeros:  9
c Status:     INTEGER OPTIMAL
c Objective:  obj = 700 (MAXimum)
c
s mip 3 3 o 700
i 1 180
i 2 600
i 3 90
j 1 40
j 2 50
j 3 0
e o f

and I can parse that.

jwaldmann commented 6 years ago

And, I just realized there may be a deeper problem: if the LP is built with execLPM (or similar), then this already uses the API, and might crash when run concurrently. But it should be possible to construct an LP in pure Haskell land.

But, even if we manage to construct the LP, the printing function writeLP does use the API, and this might be dangerous. It should be easy to write a pure prettyprinter, though.