【问题标题】:Running other programs in Haskell / Linear programming package在 Haskell / 线性编程包中运行其他程序
【发布时间】:2018-04-29 21:57:12
【问题描述】:

我有一个名为LPSolve 的程序可以解决混合整数优化问题。问题是我不能在迭代期间动态添加约束,所以我想编写一个使用LPSolve 解决松弛问题的 Haskell 程序,然后根据解决方案推断一些额外的约束。利用问题结构的约束。

是否可以在 Haskell 中运行可执行文件并检索发送到终端的输出?

是否存在解决线性规划问题的 Haskell 包?

【问题讨论】:

    标签: haskell linear-programming


    【解决方案1】:

    使用runInteractiveProcess,您可以通过标准输入/标准输出与外部进程“对话”

    【讨论】:

    • 这正是我所需要的。谢谢你:)
    【解决方案2】:

    Shelly package 有一些不错的库方法来运行外部进程。它旨在用 Haskell 编写 shell 脚本,但没有理由不能在应用程序中使用它。我发现 shell 脚本任务比标准库方法方便得多。

    【讨论】:

      【解决方案3】:

      您可以使用 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)] 
      

      【讨论】:

        【解决方案4】:

        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
        

        它求解有理系数。

        您可以添加约束并重新运行求解器:

          assertAtom solver (LA.var x .<=. LA.constant 30)
          o <- optimize solver def
          print o
          getValue solver x
        
        
        > case_test1
        Optimum
        30 % 1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-08
          • 1970-01-01
          相关资源
          最近更新 更多