2013-02-12 13 views
5

Mam program o nazwie LPSolve, który rozwiązuje problemy z optymalizacją liczby całkowitej. Problem polega na tym, że nie mogę dynamicznie dodawać wiązań podczas iteracji, więc chciałem napisać program Haskell, który używa LPSolve do rozwiązywania relaksacji, a następnie wnioskować o dodatkowych ograniczeniach opartych na rozwiązaniach. Ograniczenia, które wykorzystują strukturę problemu.Uruchamianie innych programów w pakiecie programowania Haskell/Linear

Czy można uruchomić plik wykonywalny w Haskell i pobrać wyjście wysłane do terminala?

Czy istnieje pakiet Haskell, który rozwiązuje problemy z programowaniem liniowym?

Odpowiedz

3

Można użyć glpk i stworzyć i uruchomić problemów w kodzie Haskell

-- 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)] 
4

Shelly package posiada kilka metod bibliotecznych do uruchamiania procesów zewnętrznych. Jego celem jest pisanie skryptów powłoki w Haskell, ale nie ma powodu, dla którego nie można go używać w aplikacji. Uważam, że jest to o wiele wygodniejsze w przypadku skryptów powłoki niż standardowe metody biblioteki.

Powiązane problemy