packages feed

MIP 0.1.0.0 → 0.1.1.0

raw patch · 10 files changed

+78/−23 lines, 10 filesdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Numeric.Optimization.MIP.Base: class Default a
+ Numeric.Optimization.MIP.Base: def :: Default a => a
- Numeric.Optimization.MIP: parseLPString :: FileOptions -> String -> String -> Either (ParseError String) (Problem Scientific)
+ Numeric.Optimization.MIP: parseLPString :: (Stream s, Token s ~ Char, IsString (Tokens s)) => FileOptions -> String -> s -> Either (ParseError s) (Problem Scientific)
- Numeric.Optimization.MIP: parseMPSString :: FileOptions -> String -> String -> Either (ParseError String) (Problem Scientific)
+ Numeric.Optimization.MIP: parseMPSString :: (Stream s, Token s ~ Char, IsString (Tokens s)) => FileOptions -> String -> s -> Either (ParseError s) (Problem Scientific)

Files

ChangeLog.md view
@@ -2,6 +2,12 @@  ## Unreleased changes +## 0.1.1.0++* re-export `Default` class from `Numeric.Optimization.MIP`.+* fix to work with recent version of CBC+* generalize type of `parseLPString` and `parseMPSString`+ ## 0.1.0.0  * Separated from toysolver package
MIP.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: ac803e98baaa0544b947d71e759475b741c54bd5c39105056cfd3d1fbc25b4e0+-- hash: f6b1b8d7874f11e9e522f0bba9ad5789dbfe74e4a863836348e4a8f03c658484  name:           MIP-version:        0.1.0.0+version:        0.1.1.0 synopsis:       Library for using Mixed Integer Programming (MIP) description:    Please see the README on GitHub at <https://github.com/msakai/haskell-MIP/tree/master/MIP#readme> category:       Math, Algorithms, Optimisation, Optimization@@ -31,32 +31,32 @@   location: https://github.com/msakai/haskell-MIP  flag TestCBC-  description: run test cases that depends on cbc command+  description: run test cases that depend on cbc command   manual: True   default: False  flag TestCPLEX-  description: run test cases that depends on cplex command+  description: run test cases that depend on cplex command   manual: True   default: False  flag TestGlpsol-  description: run test cases that depends on glpsol command+  description: run test cases that depend on glpsol command   manual: True   default: False  flag TestGurobiCl-  description: run test cases that depends on gurobi_cl command+  description: run test cases that depend on gurobi_cl command   manual: True   default: False  flag TestLPSolve-  description: run test cases that depends on lp_solve command+  description: run test cases that depend on lp_solve command   manual: True   default: False  flag TestSCIP-  description: run test cases that depends on scip command+  description: run test cases that depend on scip command   manual: True   default: False @@ -101,7 +101,7 @@     , filepath     , intern >=0.9.1.2 && <1.0.0.0     , lattices-    , megaparsec >=5 && <9+    , megaparsec >=5 && <10     , mtl >=2.1.2     , process >=1.1.0.2     , scientific
README.md view
@@ -1,5 +1,9 @@ # MIP +[![Hackage](https://img.shields.io/hackage/v/MIP.svg)](https://hackage.haskell.org/package/MIP)+[![Hackage Deps](https://img.shields.io/hackage-deps/v/MIP.svg)](https://packdeps.haskellers.com/feed?needle=MIP)+[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)+ Library for using Mixed Integer Programming (MIP) in Haskell. This library contains functions like: 
src/Numeric/Optimization/MIP.hs view
@@ -1,7 +1,9 @@ {-# OPTIONS_GHC -Wall #-} {-# OPTIONS_HADDOCK show-extensions #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeFamilies #-} ----------------------------------------------------------------------------- -- | -- Module      :  Numeric.Optimization.MIP@@ -16,28 +18,39 @@ -- ----------------------------------------------------------------------------- module Numeric.Optimization.MIP-  ( module Numeric.Optimization.MIP.Base+  (+  -- * The MIP Problem/Solution types+    module Numeric.Optimization.MIP.Base++  -- * File I/O+  -- $IO++  -- ** Reading problem files   , readFile   , readLPFile   , readMPSFile   , parseLPString   , parseMPSString+  , ParseError++  -- ** Generating problem files   , writeFile   , writeLPFile   , writeMPSFile   , toLPString   , toMPSString-  , ParseError   ) where  import Prelude hiding (readFile, writeFile) import Control.Exception import Data.Char import Data.Scientific (Scientific)+import Data.String import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.IO as TLIO import System.FilePath (takeExtension, splitExtension) import System.IO hiding (readFile, writeFile)+import Text.Megaparsec (Stream (..))  import Numeric.Optimization.MIP.Base import Numeric.Optimization.MIP.FileUtils (ParseError)@@ -52,7 +65,7 @@ import GHC.IO.Encoding (getLocaleEncoding) #endif --- | Parse .lp or .mps file based on file extension+-- | Parse LP or MPS file based on file extension. readFile :: FileOptions -> FilePath -> IO (Problem Scientific) readFile opt fname =   case getExt fname of@@ -105,13 +118,22 @@ #endif  -- | Parse a string containing LP file data.-parseLPString :: FileOptions -> String -> String -> Either (ParseError String) (Problem Scientific)+#if MIN_VERSION_megaparsec(6,0,0)+parseLPString :: (Stream s, Token s ~ Char, IsString (Tokens s)) => FileOptions -> String -> s -> Either (ParseError s) (Problem Scientific)+#else+parseLPString :: (Stream s, Token s ~ Char) => FileOptions -> String -> s -> Either (ParseError s) (Problem Scientific)+#endif parseLPString = LPFile.parseString  -- | Parse a string containing MPS file data.-parseMPSString :: FileOptions -> String -> String -> Either (ParseError String) (Problem Scientific)+#if MIN_VERSION_megaparsec(6,0,0)+parseMPSString :: (Stream s, Token s ~ Char, IsString (Tokens s)) => FileOptions -> String -> s -> Either (ParseError s) (Problem Scientific)+#else+parseMPSString :: (Stream s, Token s ~ Char) => FileOptions -> String -> s -> Either (ParseError s) (Problem Scientific)+#endif parseMPSString = MPSFile.parseString +-- | Generate LP file or MPS file based on file extension. writeFile :: FileOptions -> FilePath -> Problem Scientific -> IO () writeFile opt fname prob =   case getExt fname of@@ -127,12 +149,14 @@ #endif     s -> s +-- | Generate LP file. writeLPFile :: FileOptions -> FilePath -> Problem Scientific -> IO () writeLPFile opt fname prob =   case LPFile.render opt prob of     Left err -> ioError $ userError err     Right s -> writeTextFile opt fname s +-- | Generate MPS file. writeMPSFile :: FileOptions -> FilePath -> Problem Scientific -> IO () writeMPSFile opt fname prob =   case MPSFile.render opt prob of@@ -159,8 +183,14 @@   writeSimple #endif +-- | Generate a 'TL.Text' containing LP file data. toLPString :: FileOptions -> Problem Scientific -> Either String TL.Text toLPString = LPFile.render +-- | Generate a 'TL.Text' containing MPS file data. toMPSString :: FileOptions -> Problem Scientific -> Either String TL.Text toMPSString = MPSFile.render++-- $IO+-- If this library is built with @WithZlib@ flag (enabled by default), +-- reading/writing gzipped file (@.gz@) are also supported.
src/Numeric/Optimization/MIP/Base.hs view
@@ -77,6 +77,7 @@   , FileOptions (..)    -- * Utilities+  , Default (..)   , Variables (..)   , intersectBounds   ) where@@ -269,16 +270,19 @@   }   deriving (Eq, Ord, Show) +-- | Equality constraint. (.==.) :: Num c => Expr c -> Expr c -> Constraint c lhs .==. rhs =   case splitConst (lhs - rhs) of     (e, c) -> def{ constrExpr = e, constrLB = Finite (- c), constrUB = Finite (- c) } +-- | Inequality constraint (≤). (.<=.) :: Num c => Expr c -> Expr c -> Constraint c lhs .<=. rhs =   case splitConst (lhs - rhs) of     (e, c) -> def{ constrExpr = e, constrUB = Finite (- c) } +-- | Inequality constraint (≥). (.>=.) :: Num c => Expr c -> Expr c -> Constraint c lhs .>=. rhs =   case splitConst (lhs - rhs) of@@ -356,7 +360,9 @@         , (StatusInfeasibleOrUnbounded, StatusInfeasible)         ] -+-- | /meet/ (greatest lower bound) operator of the partial order of 'Status' type.+--+-- If the version of @lattices@ is \<2, then @MeetSemiLattice@ instance can also be used. meetStatus :: Status -> Status -> Status StatusUnknown `meetStatus` _b = StatusUnknown StatusFeasible `meetStatus` b@@ -387,6 +393,7 @@ #endif  +-- | Type for representing a solution of MIP problem. data Solution r   = Solution   { solStatus :: Status
src/Numeric/Optimization/MIP/FileUtils.hs view
@@ -21,6 +21,9 @@ #endif import qualified Text.Megaparsec as MP +-- | Error type for parsing.+--+-- The definition is slightly different based on the @megaparsec@ version. #if MIN_VERSION_megaparsec(7,0,0) type ParseError s = MP.ParseErrorBundle s Void #elif MIN_VERSION_megaparsec(6,0,0)
src/Numeric/Optimization/MIP/LPFile.hs view
@@ -17,7 +17,7 @@ -- Stability   :  provisional -- Portability :  non-portable ----- A CPLEX .lp format parser library.+-- A CPLEX @.lp@ format parser library. -- -- References: --@@ -87,7 +87,7 @@ #endif  -- | Parse a string containing LP file data.--- The source name is only | used in error messages and may be the empty string.+-- The source name is only used in error messages and may be the empty string. #if MIN_VERSION_megaparsec(6,0,0) parseString :: (Stream s, Token s ~ Char, IsString (Tokens s)) => MIP.FileOptions -> String -> s -> Either (ParseError s) (MIP.Problem Scientific) #else@@ -484,7 +484,7 @@  -- --------------------------------------------------------------------------- --- | Render a problem into a string.+-- | Render a problem into a 'TL.Text' containing LP file data. render :: MIP.FileOptions -> MIP.Problem Scientific -> Either String TL.Text render _ mip = Right $ execM $ render' $ normalize mip 
src/Numeric/Optimization/MIP/MPSFile.hs view
@@ -16,7 +16,7 @@ -- Stability   :  provisional -- Portability :  non-portable ----- A .mps format parser library.+-- A @.mps@ format parser library. -- -- References: --@@ -104,7 +104,7 @@ #endif  -- | Parse a string containing MPS file data.--- The source name is only | used in error messages and may be the empty string.+-- The source name is only used in error messages and may be the empty string. #if MIN_VERSION_megaparsec(6,0,0) parseString :: (Stream s, Token s ~ Char, IsString (Tokens s)) => MIP.FileOptions -> String -> s -> Either (ParseError s) (MIP.Problem Scientific) #else@@ -617,6 +617,7 @@  -- --------------------------------------------------------------------------- +-- | Render a problem into a 'TL.Text' containing MPS file data. render :: MIP.FileOptions -> MIP.Problem Scientific -> Either String TL.Text render _ mip | not (checkAtMostQuadratic mip) = Left "Expression must be atmost quadratic" render _ mip = Right $ execM $ render' $ nameRows mip
src/Numeric/Optimization/MIP/Solver/CBC.hs view
@@ -41,7 +41,7 @@  instance IsSolver CBC IO where   solve solver opt prob = do-    case LPFile.render def prob of+    case LPFile.render def prob{ MIP.objectiveFunction = obj' } of       Left err -> ioError $ userError err       Right lp -> do         withSystemTempFile "cbc.lp" $ \fname1 h1 -> do@@ -61,7 +61,11 @@               ExitFailure n -> ioError $ userError $ "exit with " ++ show n               ExitSuccess -> do                 sol <- CBCSol.readFile fname2-                if MIP.objDir (MIP.objectiveFunction prob) == MIP.OptMax then+                if isMax then                   return $ sol{ MIP.solObjectiveValue = fmap negate (MIP.solObjectiveValue sol) }                 else                   return sol+    where+      obj = MIP.objectiveFunction prob+      isMax = MIP.objDir obj == MIP.OptMax+      obj' = if isMax then obj{ MIP.objDir = MIP.OptMin, MIP.objExpr = - MIP.objExpr obj } else obj
test/TestSuite.hs view
@@ -8,7 +8,7 @@ import Test.MPSFile  main :: IO ()-main = defaultMain $ testGroup "ToySolver test suite"+main = defaultMain $ testGroup "MIP test suite"   [ lpTestGroup   , mipTestGroup   , mipSolverTestGroup