在Haskell/线性规划包中运行其他程序
我有一个名为在Haskell/线性规划包中运行其他程序,haskell,linear-programming,Haskell,Linear Programming,我有一个名为LPSolve的程序,可以解决混合整数优化问题。问题是我无法在迭代过程中动态添加约束,因此我考虑编写一个Haskell程序,使用LPSolve解决松弛问题,然后根据解决方案推断出一些附加约束。利用问题结构的约束 是否可以在Haskell中运行可执行文件并检索发送到终端的输出 是否存在解决线性规划问题的Haskell包?通过stdin/stdout与外部进程“对话”您可以使用GLPK创建问题并将其运行到Haskell代码中 -- Usando GLPK, http://www.gnu.
LPSolve
的程序,可以解决混合整数优化问题。问题是我无法在迭代过程中动态添加约束,因此我考虑编写一个Haskell程序,使用LPSolve
解决松弛问题,然后根据解决方案推断出一些附加约束。利用问题结构的约束
是否可以在Haskell中运行可执行文件并检索发送到终端的输出
是否存在解决线性规划问题的Haskell包?通过stdin/stdout与外部进程“对话”您可以使用GLPK创建问题并将其运行到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)]
--Usando GLPK,http://www.gnu.org/software/glpk/
导入数据。列表
导入数据,也许吧
进口管制
导入Data.LinearProgram
导入Data.LinearProgram.GLPK
导入符合条件的数据。映射为M
--Sólo por dar nombre a las varibles
x e=“x”++显示e
--在就业方面的问题
solveEmployees::[(Int,Int)]->LP String Int
solves=execLPM$do setDirection Min
setObjective$linCombination$map(\e->(1,x e))环境管理计划
mapM \(\(a,b)->geqTo(varSum[xa,xb])1
mapM(\n->setVarKind(x n)BinVar)emps
其中emps=nub$map fst es++map snd es
--包装商suponiendo que siempre hay solución(阿奎西姆普)
getEmployees::[(Int,Int)]->IO[Int]
getes=do
(,Just(m))有一些很好的库方法来运行外部进程。它旨在用Haskell编写shell脚本,但没有理由不能在应用程序中使用它。我发现shell脚本任务比标准库方法方便得多。有toysolver
import Data.Default.Class(def)
导入ToySolver.Arith.Simplex
将合格的ToySolver.Data.LA作为LA导入
case_test1=do
这正是我需要的。谢谢:)
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
assertAtom solver (LA.var x .<=. LA.constant 30)
o <- optimize solver def
print o
getValue solver x
> case_test1
Optimum
30 % 1