2013-02-12 15 views
5

Ho un programma chiamato LPSolve che risolve problemi di ottimizzazione di interi misti. Il problema è che non posso aggiungere dinamicamente dei vincoli durante le iterazioni, quindi penso di scrivere un programma Haskell che usa LPSolve per risolvere i rilassamenti e quindi dedurre alcuni vincoli aggiuntivi basati sulle soluzioni. Vincoli che fanno uso della struttura del problema.Esecuzione di altri programmi nel pacchetto di programmazione Haskell/Linear

È possibile eseguire un eseguibile in Haskell e recuperare l'output inviato al terminale?

Esiste un pacchetto Haskell che risolve problemi di programmazione lineare?

risposta

3

È possibile utilizzare GLPK e creare ed eseguire problemi in codice 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

Il Shelly package ha alcune belle metodi di libreria per l'esecuzione di processi esterni. Ha lo scopo di scrivere script di shell in Haskell, ma non c'è motivo per cui non si possa usarlo in un'applicazione. Trovo molto più conveniente per le attività di scripting di shell rispetto ai metodi di libreria standard.