Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
A library for modeling and solving linear and integer programs.
This library is merely a frontend to various solver backends. At the time this was written, the only known supported backend is GLPK.
This page includes a high-level overview of the model building DSL, as well as a deeper dive into the core monadic interface.
Synopsis
- free :: MonadLP v c o m => m v
- bounded :: MonadLP v c o m => Double -> Double -> m v
- nonNeg :: MonadLP v c o m => m v
- nonPos :: MonadLP v c o m => m v
- integer :: MonadIP v c o m => m v
- binary :: MonadIP v c o m => m v
- nonNegInteger :: MonadIP v c o m => m v
- nonPosInteger :: MonadIP v c o m => m v
- within :: MonadLP v c o m => m v -> Bounds -> m v
- asKind :: MonadIP v c o m => m v -> Domain -> m v
- (.==.) :: MonadLP v c o m => Expr v -> Expr v -> m c
- (==.) :: MonadLP v c o m => Double -> Expr v -> m c
- (.==) :: MonadLP v c o m => Expr v -> Double -> m c
- (.<=.) :: MonadLP v c o m => Expr v -> Expr v -> m c
- (<=.) :: MonadLP v c o m => Double -> Expr v -> m c
- (.<=) :: MonadLP v c o m => Expr v -> Double -> m c
- (.>=.) :: MonadLP v c o m => Expr v -> Expr v -> m c
- (>=.) :: MonadLP v c o m => Double -> Expr v -> m c
- (.>=) :: MonadLP v c o m => Expr v -> Double -> m c
- minimize :: MonadLP v c o m => Expr v -> m o
- maximize :: MonadLP v c o m => Expr v -> m o
- var :: Num a => b -> LinExpr a b
- con :: a -> LinExpr a b
- (.*) :: Num a => b -> a -> LinExpr a b
- (*.) :: Num a => a -> b -> LinExpr a b
- (.+.) :: Num a => LinExpr a b -> LinExpr a b -> LinExpr a b
- (.-.) :: Num a => LinExpr a b -> LinExpr a b -> LinExpr a b
- (./) :: Fractional a => b -> a -> LinExpr a b
- eval :: Num a => LinExpr a a -> a
- simplify :: (Num a, Ord b) => LinExpr a b -> LinExpr a b
- vsum :: Num a => [b] -> LinExpr a b
- esum :: Num a => Foldable t => t (LinExpr a b) -> LinExpr a b
- scale :: Num a => a -> LinExpr a b -> LinExpr a b
- class Monad m => MonadLP v c o m | m -> v c o where
- addVariable :: m v
- deleteVariable :: v -> m ()
- getVariableName :: v -> m Text
- setVariableName :: v -> Text -> m ()
- getVariableBounds :: v -> m Bounds
- setVariableBounds :: v -> Bounds -> m ()
- getVariableValue :: v -> m Double
- addConstraint :: Inequality (Expr v) -> m c
- deleteConstraint :: c -> m ()
- getConstraintName :: c -> m Text
- setConstraintName :: c -> Text -> m ()
- getConstraintValue :: c -> m Double
- addObjective :: Expr v -> m o
- deleteObjective :: o -> m ()
- getObjectiveName :: o -> m Text
- setObjectiveName :: o -> Text -> m ()
- getObjectiveSense :: o -> m Sense
- setObjectiveSense :: o -> Sense -> m ()
- getObjectiveValue :: o -> m Double
- getTimeout :: m Double
- setTimeout :: Double -> m ()
- optimizeLP :: m SolutionStatus
- class MonadLP v c o m => MonadIP v c o m | m -> v c o where
- getVariableDomain :: v -> m Domain
- setVariableDomain :: v -> Domain -> m ()
- getRelativeMIPGap :: m Double
- setRelativeMIPGap :: Double -> m ()
- optimizeIP :: m SolutionStatus
- data Domain
- = Continuous
- | Integer
- | Binary
- evalExpr :: MonadLP v c o m => Expr v -> m Double
- formatExpr :: MonadLP v c o m => Expr v -> m Text
- type Expr = LinExpr Double
- data Bounds
- data SolutionStatus
- = Optimal
- | Feasible
- | Infeasible
- | Unbounded
- | Error
- data Sense
- data Inequality a = Inequality Ordering a a
- data LinExpr a b = LinExpr ![(a, b)] !a
- withVariableName :: MonadLP v c o m => m v -> Text -> m v
- withConstraintName :: MonadLP v c o m => m c -> Text -> m c
- withObjectiveName :: MonadLP v c o m => m o -> Text -> m o
Model-building DSL
We provide a monadic DSL for specifying math programs. This DSL builds up programs statefully, rather than building some pure, abstract representation of a math program.
Creating variables
Continuous variables
bounded :: MonadLP v c o m => Double -> Double -> m v Source #
Create a new variable bounded between two values.
Discrete variables
nonNegInteger :: MonadIP v c o m => m v Source #
Create an integer-value variable that takes on non-negative values.
nonPosInteger :: MonadIP v c o m => m v Source #
Create an integer-value variable that takes on non-positive values.
Modifying variables
Regardless of the helper functions used above to create a variable, you can modify its behavior using the following modifiers.
Creating constraints
An
is an inequality over the type Inequality
aa
, which in
turn is typically an
for some variable type Expr
vv
. Despite
the name, Inequality
can also represent equality constraints
directly.
As an alternative to constructing an inequality and passing it to
addConstraint
, we can use the convenience operators below. Since
linear programming constraints often involve constant bounds, we
offer operators specialized for both expressions and constants. The
mnemonic is that .
characters point to expressions
Equality constraints
(==.) :: MonadLP v c o m => Double -> Expr v -> m c infix 4 Source #
An equality constraint with a numeric left-hand side
(.==) :: MonadLP v c o m => Expr v -> Double -> m c infix 4 Source #
An equality constraint with a numeric right-hand side
Less-than constraints
(.<=.) :: MonadLP v c o m => Expr v -> Expr v -> m c infix 4 Source #
A less-than or equal-to constraint
(<=.) :: MonadLP v c o m => Double -> Expr v -> m c infix 4 Source #
A less-than or equal-to constraint with a numeric left-hand side
(.<=) :: MonadLP v c o m => Expr v -> Double -> m c infix 4 Source #
A less-than or equal-to constraint with a numeric right-hand side
Greater-than constraints
(.>=.) :: MonadLP v c o m => Expr v -> Expr v -> m c infix 4 Source #
A greater-than or equal-to constraint
(>=.) :: MonadLP v c o m => Double -> Expr v -> m c infix 4 Source #
A greater-than or equal-to constraint with a numeric left-hand side
(.>=) :: MonadLP v c o m => Expr v -> Double -> m c infix 4 Source #
A greater-than or equal-to constraint with a numeric right-hand side
Creating objectives
Creating linear expressions
A
is a linear expression over variables of type LinExpr
a bb
with coefficients of type a
(typically Double
.) We provide a
number of operators to build up linear expressions naturally. The
mnemonic is that .
characters point to expressions.
(.*) :: Num a => b -> a -> LinExpr a b infixl 7 Source #
Construct a term in a linear expression by multiplying a variable by a constant.
(*.) :: Num a => a -> b -> LinExpr a b infixl 7 Source #
Construct a term in a linear expression by multiplying a constant by a variable.
(.+.) :: Num a => LinExpr a b -> LinExpr a b -> LinExpr a b infixl 6 Source #
Addition of linear expressions.
(.-.) :: Num a => LinExpr a b -> LinExpr a b -> LinExpr a b infixl 6 Source #
The difference of linear expressions.
(./) :: Fractional a => b -> a -> LinExpr a b infixl 7 Source #
Construct a term in a linear expression by dividing a variable by a constant.
simplify :: (Num a, Ord b) => LinExpr a b -> LinExpr a b Source #
Simplify an expression by grouping like terms.
esum :: Num a => Foldable t => t (LinExpr a b) -> LinExpr a b Source #
The sum of linear expressions.
scale :: Num a => a -> LinExpr a b -> LinExpr a b Source #
Multiplication of linear expressions by a constant.
Math programs
The MonadLP
and MonadIP
classes provide low-level APIs for
defining linear and integer programs, respectively, although the
high-level DSL will typically be easier to work with.
Linear programs
class Monad m => MonadLP v c o m | m -> v c o where Source #
A linear program.
This is a monadic context for formulating and solving linear
programs. The types v
, c
, and o
refer to the types of
variables, constraints, and objectives, respectively, used by a
particular solver backend.
addVariable :: m v Source #
Add a new (free) variable to the model.
See free
, bounded
,
nonNeg
, and nonPos
as higher-level alternatives.
deleteVariable :: v -> m () Source #
Remove a variable from the model.
getVariableName :: v -> m Text Source #
Get the name of a variable.
setVariableName :: v -> Text -> m () Source #
Set a name for a variable.
getVariableBounds :: v -> m Bounds Source #
Retrieve the current bounds associated with a variable.
setVariableBounds :: v -> Bounds -> m () Source #
Apply bounds to a variable.
See within
as a higher-level alternative.
getVariableValue :: v -> m Double Source #
Get the value of a variable in the current solution.
This value could be arbitrary if no solve has been completed, or a solve produced an infeasible or unbounded solution.
addConstraint :: Inequality (Expr v) -> m c Source #
Add a constraint representing the given inequality to the model.
See the .==.
, .==#
,
==.
, .>=.
,
.>=
, >=.
,
.<=.
, .<=
, and
<=.
functions as higher-level
alternatives.
deleteConstraint :: c -> m () Source #
Remove a constraint from the model.
getConstraintName :: c -> m Text Source #
Get the name of a constraint.
setConstraintName :: c -> Text -> m () Source #
Set a name for a constraint.
getConstraintValue :: c -> m Double Source #
Get the dual value associated with a constraint.
addObjective :: Expr v -> m o Source #
Add an objective to the problem.
Depending on the solver backend, this might replace an existing objective.
deleteObjective :: o -> m () Source #
Remove an objective from the model.
getObjectiveName :: o -> m Text Source #
Get the name of a objective.
setObjectiveName :: o -> Text -> m () Source #
Set a name for a objective.
getObjectiveSense :: o -> m Sense Source #
Get the sense of an objective.
setObjectiveSense :: o -> Sense -> m () Source #
Set the sense of an objective.
getObjectiveValue :: o -> m Double Source #
Get the value of an objective.
getTimeout :: m Double Source #
Get the timeout associated with a problem.
setTimeout :: Double -> m () Source #
Set the timeout associated with a problem.
optimizeLP :: m SolutionStatus Source #
Compute an LP-optimal solution.
Instances
Integer programs
class MonadLP v c o m => MonadIP v c o m | m -> v c o where Source #
A (mixed) integer program.
In addition to the methods of the MonadLP
class, this monad
supports constraining variables to be either continuous or
discrete.
getVariableDomain :: v -> m Domain Source #
setVariableDomain :: v -> Domain -> m () Source #
getRelativeMIPGap :: m Double Source #
setRelativeMIPGap :: Double -> m () Source #
optimizeIP :: m SolutionStatus Source #
Instances
MonadIP v c o m => MonadIP v c o (ReaderT r m) Source # | |
Defined in Math.Programming.Types getVariableDomain :: v -> ReaderT r m Domain Source # setVariableDomain :: v -> Domain -> ReaderT r m () Source # getRelativeMIPGap :: ReaderT r m Double Source # setRelativeMIPGap :: Double -> ReaderT r m () Source # optimizeIP :: ReaderT r m SolutionStatus Source # | |
MonadIP v c o m => MonadIP v c o (StateT s m) Source # | |
Defined in Math.Programming.Types getVariableDomain :: v -> StateT s m Domain Source # setVariableDomain :: v -> Domain -> StateT s m () Source # getRelativeMIPGap :: StateT s m Double Source # setRelativeMIPGap :: Double -> StateT s m () Source # optimizeIP :: StateT s m SolutionStatus Source # |
The type of values that a variable can take on.
Note that the Integer
constructor does not interfere with the
Integer
type, as the Integer
type does not define a constuctor
of the same name. The ambiguity is unfortunate, but other natural
nomenclature such as Integral
are similarly conflicted.
Continuous | The variable lies in the real numbers |
Integer | The variable lies in the integers |
Binary | The variable lies in the set |
Other types and functions
evalExpr :: MonadLP v c o m => Expr v -> m Double Source #
Get the value of a linear expression in the current solution.
type Expr = LinExpr Double Source #
A convient shorthand for the type of linear expressions used in models.
An interval of the real numbers.
NonNegativeReals | The non-negative reals. |
NonPositiveReals | The non-positive reals. |
Interval Double Double | Any closed interval of the reals. |
Free | Any real number. |
data SolutionStatus Source #
The outcome of an optimization.
Optimal | An optimal solution has been found. |
Feasible | A feasible solution has been found. The result may or may not be optimal. |
Infeasible | The model has been proven to be infeasible. |
Unbounded | The model has been proven to be unbounded. |
Error | An error was encountered during the solve. Instance-specific methods should be used to determine what occurred. |
Instances
Read SolutionStatus Source # | |
Defined in Math.Programming.Types readsPrec :: Int -> ReadS SolutionStatus # readList :: ReadS [SolutionStatus] # | |
Show SolutionStatus Source # | |
Defined in Math.Programming.Types showsPrec :: Int -> SolutionStatus -> ShowS # show :: SolutionStatus -> String # showList :: [SolutionStatus] -> ShowS # | |
Eq SolutionStatus Source # | |
Defined in Math.Programming.Types (==) :: SolutionStatus -> SolutionStatus -> Bool # (/=) :: SolutionStatus -> SolutionStatus -> Bool # | |
Ord SolutionStatus Source # | |
Defined in Math.Programming.Types compare :: SolutionStatus -> SolutionStatus -> Ordering # (<) :: SolutionStatus -> SolutionStatus -> Bool # (<=) :: SolutionStatus -> SolutionStatus -> Bool # (>) :: SolutionStatus -> SolutionStatus -> Bool # (>=) :: SolutionStatus -> SolutionStatus -> Bool # max :: SolutionStatus -> SolutionStatus -> SolutionStatus # min :: SolutionStatus -> SolutionStatus -> SolutionStatus # |
Whether a math program is minimizing or maximizing its objective.
data Inequality a Source #
Non-strict inequalities.
Inequality Ordering a a |
Instances
A linear expression.
Linear expressions contain symbolic variables of type b
and
numeric coefficients of type a
. Often a
will be Double
, and
b
will be whatever variable type your linear program uses.
LinExpr ![(a, b)] !a |
Instances
Foldable (LinExpr a) Source # | |
Defined in Math.Programming.LinExpr fold :: Monoid m => LinExpr a m -> m # foldMap :: Monoid m => (a0 -> m) -> LinExpr a a0 -> m # foldMap' :: Monoid m => (a0 -> m) -> LinExpr a a0 -> m # foldr :: (a0 -> b -> b) -> b -> LinExpr a a0 -> b # foldr' :: (a0 -> b -> b) -> b -> LinExpr a a0 -> b # foldl :: (b -> a0 -> b) -> b -> LinExpr a a0 -> b # foldl' :: (b -> a0 -> b) -> b -> LinExpr a a0 -> b # foldr1 :: (a0 -> a0 -> a0) -> LinExpr a a0 -> a0 # foldl1 :: (a0 -> a0 -> a0) -> LinExpr a a0 -> a0 # toList :: LinExpr a a0 -> [a0] # null :: LinExpr a a0 -> Bool # length :: LinExpr a a0 -> Int # elem :: Eq a0 => a0 -> LinExpr a a0 -> Bool # maximum :: Ord a0 => LinExpr a a0 -> a0 # minimum :: Ord a0 => LinExpr a a0 -> a0 # | |
Traversable (LinExpr a) Source # | |
Defined in Math.Programming.LinExpr | |
Functor (LinExpr a) Source # | |
Num a => Monoid (LinExpr a b) Source # | |
Num a => Semigroup (LinExpr a b) Source # | |
(Read a, Read b) => Read (LinExpr a b) Source # | |
(Show a, Show b) => Show (LinExpr a b) Source # | |
(Eq a, Eq b) => Eq (LinExpr a b) Source # | |
Naming model attributes
withVariableName :: MonadLP v c o m => m v -> Text -> m v Source #
withConstraintName :: MonadLP v c o m => m c -> Text -> m c Source #
withObjectiveName :: MonadLP v c o m => m o -> Text -> m o Source #