Running other programs in Haskell / Linear programming package
Asked Answered
E

4

5

I have a program called LPSolve that solves mixed integer optimization problems. The problem is that I can't dynamically add constraints during iterations, so I though about writing a Haskell program that uses LPSolve to solve relaxations and then infer some additional constraints based on the solutions. Constraints that make use of the problem structure.

Is it possible to run an executable in Haskell and retrieve the output sent to the terminal?

Does there exist a Haskell package that solves linear programming problems?

Emplacement answered 12/2, 2013 at 11:40 Comment(0)
R
5

With runInteractiveProcess you can 'talk' to a extern process via stdin/stdout

Rattlebox answered 12/2, 2013 at 12:6 Comment(0)
P
4

The Shelly package has some nice library methods for running external processes. It's aimed at writing shell scripts in Haskell but there's no reason you couldn't use it in an application. I find it far more convenient for shell scripting tasks than the standard library methods.

Pyrrha answered 12/2, 2013 at 13:40 Comment(0)
M
3

You can use GLPK and create and run problems into Haskell code

-- Usando GLPK, http://www.gnu.org/software/glpk/ 
import Data.List 
import Data.Maybe 
import Control.Monad 
import Data.LinearProgram 
import Data.LinearProgram.GLPK 
import qualified Data.Map as M 

-- Sólo por dar nombre a las varibles 
x e = "X" ++ show e 

-- Resuelve el problema de elegir el menor número de empleados 
solveEmployees :: [(Int, Int)] -> LP String Int 
solveEmployees es = execLPM $ do  setDirection Min 
                                  setObjective $ linCombination $ map (\e -> (1, x e)) emps 
                                  mapM_ (\(a, b) -> geqTo (varSum [x a, x b]) 1) es 
                                  mapM_ (\n -> setVarKind (x n) BinVar) emps 
                                  where emps = nub $ map fst es ++ map snd es 

-- Wrapper suponiendo que siempre hay solución (aquí siempre) 
getEmployees :: [(Int, Int)] -> IO [Int] 
getEmployees es = do 
  (_, Just (_, m)) <- glpSolveVars mipDefaults $ solveEmployees es 
  return $ map (read.tail.fst). M.toList. M.filter (==1) $ m 

-- Tráfico de influencias, intentaremos que el empleado 'e' vaya a la playa 
--       (da igual que sea de Estocolmo o de Londres) 
getEmployees' :: Int -> [(Int, Int)] -> IO [Int] 
getEmployees' e es = do 
  r <- getEmployees es 
  r' <- getEmployees $ filter (\(a, b ) -> a /= e && b /= e) es 
  return $ if length r == 1 + length r' then e: r' else r 

-- Test 
main = do 
  putStrLn $ "Input: " ++ show test2 
  putStrLn "Testing: solveEmployees" 
  r1 <- getEmployees test2 
  putStrLn $ show r1 
  putStrLn "Testing: solveEmployees' 2001" 
  r2 <- getEmployees' 2001 test2 
  putStrLn $ show r2 

test1 :: [(Int, Int)] 
test1 = [(1009, 2011), (1017, 2011)] 

test2 :: [(Int, Int)] 
test2 = [(1009, 2000), (1009, 2001), (1008, 2000), (1008, 2001)] 
Muticous answered 12/2, 2013 at 12:36 Comment(0)
G
0

There is toysolver.

import           Data.Default.Class (def)
import           ToySolver.Arith.Simplex
import qualified ToySolver.Data.LA            as LA

case_test1 = do
  solver <- newSolver
  x <- newVar solver
  y <- newVar solver
  z <- newVar solver
  assertAtom solver (LA.fromTerms [(7,x), (12,y), (31,z)] .==. LA.constant 17)
  assertAtom solver (LA.fromTerms [(3,x), (5,y), (14,z)]  .==. LA.constant 7)
  assertAtom solver (LA.var x .>=. LA.constant 1)
  assertAtom solver (LA.var x .<=. LA.constant 40)
  assertAtom solver (LA.var y .>=. LA.constant (-50))
  assertAtom solver (LA.var y .<=. LA.constant 50)

  setObj solver (LA.fromTerms [(-1,x), (-2,x), (-3,x)])

  o <- optimize solver def
  print o
  getValue solver x


> case_test1
Optimum
40 % 1

It solves for rational coefficients.

You can add a constraint an re-run the solver:

  assertAtom solver (LA.var x .<=. LA.constant 30)
  o <- optimize solver def
  print o
  getValue solver x


> case_test1
Optimum
30 % 1
Galliard answered 29/4, 2018 at 13:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.