Pertanyaan Menjalankan program lain dalam paket pemrograman Haskell / Linear


Saya punya program yang disebut LPSolve yang memecahkan masalah optimasi bilangan bulat campuran. Masalahnya adalah saya tidak dapat secara dinamis menambahkan batasan selama iterasi, jadi saya berpikir tentang menulis program Haskell yang digunakan LPSolve untuk menyelesaikan relaksasi dan kemudian menyimpulkan beberapa kendala tambahan berdasarkan solusi. Batasan yang memanfaatkan struktur masalah.

Apakah mungkin menjalankan executable di Haskell dan mengambil output yang dikirim ke terminal?

Apakah ada paket Haskell yang memecahkan masalah pemrograman linier?


5
2018-02-12 11:40


asal


Jawaban:


Dengan runInteractiveProcess Anda dapat 'berbicara' ke proses eksternal melalui stdin / stdout


5
2018-02-12 12:06



Itu Paket Shelly memiliki beberapa metode pustaka yang bagus untuk menjalankan proses eksternal. Ini bertujuan untuk menulis skrip shell di Haskell tetapi tidak ada alasan Anda tidak bisa menggunakannya dalam aplikasi. Saya merasa jauh lebih nyaman untuk tugas-tugas shell scripting daripada metode pustaka standar.


4
2018-02-12 13:40



Anda dapat menggunakan GLPK dan membuat dan menjalankan masalah ke kode 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)] 

3
2018-02-12 12:36



Ada 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

Ini memecahkan untuk koefisien rasional.

Anda dapat menambahkan kendala menjalankan kembali solver:

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


> case_test1
Optimum
30 % 1

0
2018-04-29 13:57