For reference: any Ord type can be used as a variable. (It's pretty sweet.)<br><br>However, you have a good point. I just uploaded the newest version, which provides a newVariables monad operation for Enums. (This makes a key assumption that any element of [v..] will compare as greater than or equal to v, and that only the first element is equal to v...but that's true for most Enum implementors, and certainly most of the ones you'd be using as variables.)<br>
<br>Now, your method would look like<br><br>[x1, x2, x3] <- newVariables 3<br><br>Alternately, <br><br>(x1:x2:x3:_) <- newVariables' -- returns an infinite list<br><br>It's an expensive operation, though -- since I don't track the set of all variables as the LP is built, I need to construct the set of all variables before generating new ones -- so it's recommended that you get all the variables you need in one or two passes.<br>
<br>(The new version has a few other neat features, like exporting/importing from CPLEX LP files. I've kind of been overdoing the Haskell lately...)<br><br clear="all">Louis Wasserman<br><a href="mailto:wasserman.louis@gmail.com">wasserman.louis@gmail.com</a><br>
<a href="http://profiles.google.com/wasserman.louis">http://profiles.google.com/wasserman.louis</a><br>
<br><br><div class="gmail_quote">On Sun, Feb 28, 2010 at 5:24 PM, Henning Thielemann <span dir="ltr"><<a href="mailto:schlepptop@henning-thielemann.de">schlepptop@henning-thielemann.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Louis Wasserman schrieb:<div class="im"><br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Yo,<br>
<br>
Man, I'd never used FFI before, but it's really not as scary as I'd feared.<br>
<br>
I've implemented a more comprehensive interface to GLPK's simplex solver and -- rather importantly, for my own needs -- its MIP solver. This doesn't depend on hmatrix, and in fact, it doesn't require any matrix or vector manipulation at all -- linear functions are specified as a straight-up Data.Map from an arbitrary variable type to their coefficients.<br>
<br>
The library is now available as glpk-hs on hackage.<br>
<br>
Example:<br>
<br>
import Data.LinearProgram.LPMonad<br>
import Data.LinearProgram<br>
import Data.LinearProgram.GLPK<br>
<br>
objFun :: LinFunc String Int<br>
objFun = linCombination [(10, "x1"), (6, "x2"), (4, "x3")]<br>
<br>
lp :: LP String Int<br>
lp = execLPM $ do setDirection Max<br>
setObjective objFun<br>
leqTo (varSum ["x1", "x2", "x3"]) 100<br>
leqTo (10 *^ var "x1" ^+^ 4 *& "x2" ^+^ 5 *^ var "x3") 600<br>
-- c *^ var v, c *& v, and linCombination [(c, v)] are all equivalent.<br>
-- ^+^ is the addition operation on linear functions.<br>
leqTo (linCombination [(2, "x1"), (2, "x2"), (6, "x3")]) 300<br>
varGeq "x1" 0<br>
varBds "x2" 0 50<br>
varGeq "x3" 0<br>
setVarKind "x1" IntVar<br>
setVarKind "x2" ContVar<br>
</blockquote></div>
Using strings for variable names you cannot check for undefined variables. How about adding a function for generating new variables to your LP monad?<br>
The example may then look like<div class="im"><br>
<br>
do<br>
setDirection Max<br>
setObjective objFun<br></div>
x1 <- newVariable<br>
x2 <- newVariable<br>
x3 <- newVariable<div class="im"><br>
leqTo (varSum [x1,x2,x3]) 100<br></div>
...<br>
<br>
<br>
</blockquote></div><br>