Skip to content

Commit b377658

Browse files
authored
Update docs (#11)
1 parent 84c89e7 commit b377658

File tree

2 files changed

+59
-49
lines changed

2 files changed

+59
-49
lines changed

README.md

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,97 +11,105 @@ The `Linear.Simplex.Solver.TwoPhase` module contain both phases of the two-phase
1111
Phase one is implemented by `findFeasibleSolution`:
1212

1313
```haskell
14-
findFeasibleSolution :: [PolyConstraint] -> Maybe (DictionaryForm, [Integer], [Integer], Integer)
14+
findFeasibleSolution :: (MonadIO m, MonadLogger m) => [PolyConstraint] -> m (Maybe FeasibleSystem)
1515
```
1616

1717
`findFeasibleSolution` takes a list of `PolyConstraint`s.
1818
The `PolyConstraint` type, as well as other custom types required by this library, are defined in the `Linear.Simplex.Types` module.
1919
`PolyConstraint` is defined as:
2020

2121
```haskell
22-
data PolyConstraint =
23-
LEQ Vars Rational |
24-
GEQ Vars Rational |
25-
EQ Vars Rational deriving (Show, Eq);
22+
data PolyConstraint
23+
= LEQ {lhs :: VarLitMapSum, rhs :: SimplexNum}
24+
| GEQ {lhs :: VarLitMapSum, rhs :: SimplexNum}
25+
| EQ {lhs :: VarLitMapSum, rhs :: SimplexNum}
26+
deriving (Show, Read, Eq, Generic)
2627
```
2728

28-
And `Vars` is defined as:
29+
`SimplexNum` is an alias for `Rational`, and `VarLitMapSum` is an alias for `VarLitMap`, which is an alias for `Map Var SimplexNum`.
30+
`Var` is an alias of `Int`.
2931

30-
```haskell
31-
type Vars = [(Integer, Rational)]
32-
```
32+
A `VarLitMapSum` is read as `Integer` variables mapped to their `Rational` coefficients, with an implicit `+` between each entry.
33+
For example: `Map.fromList [(1, 2), (2, (-3)), (1, 3)]` is equivalent to `(2x1 + (-3x2) + 3x1)`.
3334

34-
A `Vars` is treated as a list of `Integer` variables mapped to their `Rational` coefficients, with an implicit `+` between each element in the list.
35-
For example: `[(1, 2), (2, (-3)), (1, 3)]` is equivalent to `(2x1 + (-3x2) + 3x1)`.
35+
And a `PolyConstraint` is an inequality/equality where the LHS is a `VarLitMapSum` and the RHS is a `Rational`.
36+
For example: `LEQ (Map.fromList [(1, 2), (2, (-3)), (1, 3)] 60)` is equivalent to `(2x1 + (-3x2) + 3x1) <= 60`.
3637

37-
And a `PolyConstraint` is an inequality/equality where the LHS is a `Vars` and the RHS is a `Rational`.
38-
For example: `LEQ [(1, 2), (2, (-3)), (1, 3)] 60` is equivalent to `(2x1 + (-3x2) + 3x1) <= 60`.
38+
Passing a `[PolyConstraint]` to `findFeasibleSolution` will return a `FeasibleSystem` if a feasible solution exists:
3939

40-
Passing a `[PolyConstraint]` to `findFeasibleSolution` will return a feasible solution if it exists as well as a list of slack variables, artificial variables, and a variable that can be safely used to represent the objective for phase two.
41-
`Nothing` is returned if the given `[PolyConstraint]` is infeasible.
42-
The feasible system is returned as the type `DictionaryForm`:
40+
```haskell
41+
data FeasibleSystem = FeasibleSystem
42+
{ dict :: Dict
43+
, slackVars :: [Var]
44+
, artificialVars :: [Var]
45+
, objectiveVar :: Var
46+
}
47+
deriving (Show, Read, Eq, Generic)
48+
```
4349

4450
```haskell
45-
type DictionaryForm = [(Integer, Vars)]
51+
type Dict = M.Map Var DictValue
52+
53+
data DictValue = DictValue
54+
{ varMapSum :: VarLitMapSum
55+
, constant :: SimplexNum
56+
}
57+
deriving (Show, Read, Eq, Generic)
4658
```
4759

48-
`DictionaryForm` can be thought of as a list of equations, where the `Integer` represents a basic variable on the LHS that is equal to the RHS represented as a `Vars`. In this `Vars`, the `Integer` -1 is used internally to represent a `Rational` number.
60+
`Dict` can be thought of as a set of equations, where the key represents a basic variable on the LHS of the equation
61+
that is equal to the RHS represented as a `DictValue` value.
4962

5063
### Phase Two
5164

5265
`optimizeFeasibleSystem` performs phase two of the simplex method, and has the type:
5366

5467
```haskell
55-
data ObjectiveFunction = Max Vars | Min Vars deriving (Show, Eq)
5668

57-
optimizeFeasibleSystem :: ObjectiveFunction -> DictionaryForm -> [Integer] -> [Integer] -> Integer -> Maybe (Integer, [(Integer, Rational)])
69+
optimizeFeasibleSystem :: (MonadIO m, MonadLogger m) => ObjectiveFunction -> FeasibleSystem -> m (Maybe Result)
70+
71+
data ObjectiveFunction = Max {objective :: VarLitMapSum} | Min {objective :: VarLitMapSum}
72+
73+
data Result = Result
74+
{ objectiveVar :: Var
75+
, varValMap :: VarLitMap
76+
}
77+
deriving (Show, Read, Eq, Generic)
5878
```
5979

60-
We first pass an `ObjectiveFunction`.
61-
Then we give a feasible system in `DictionaryForm`, a list of slack variables, a list of artificial variables, and a variable to represent the objective.
62-
`optimizeFeasibleSystem` Maximizes/Minimizes the linear equation represented as a `Vars` in the given `ObjectiveFunction`.
63-
The first item of the returned pair is the `Integer` variable representing the objective.
64-
The second item is a list of `Integer` variables mapped to their optimized values.
65-
If a variable is not in this list, the variable is equal to 0.
80+
We give `optimizeFeasibleSystem` an `ObjectiveFunction` along with a `FeasibleSystem`.
6681

6782
### Two-Phase Simplex
6883

6984
`twoPhaseSimplex` performs both phases of the simplex method.
7085
It has the type:
7186

7287
```haskell
73-
twoPhaseSimplex :: ObjectiveFunction -> [PolyConstraint] -> Maybe (Integer, [(Integer, Rational)])
88+
twoPhaseSimplex :: (MonadIO m, MonadLogger m) => ObjectiveFunction -> [PolyConstraint] -> m (Maybe Result)
7489
```
7590

76-
The return type is the same as that of `optimizeFeasibleSystem`
77-
7891
### Extracting Results
7992

80-
The result of the objective function is present in the return type of both `twoPhaseSimplex` and `optimizeFeasibleSystem`, but this can be difficult to grok in systems with many variables, so the following function will extract the value of the objective function for you.
93+
The result of the objective function is present in the returned `Result` type of both `twoPhaseSimplex` and `optimizeFeasibleSystem`, but this can be difficult to grok in systems with many variables, so the following function will extract the value of the objective function for you.
8194

8295
```haskell
83-
extractObjectiveValue :: Maybe (Integer, [(Integer, Rational)]) -> Maybe Rational
96+
dictionaryFormToTableau :: Dict -> Tableau
8497
```
8598

8699
There are similar functions for `DictionaryForm` as well as other custom types in the module `Linear.Simplex.Util`.
87100

88-
## Usage notes
89-
90-
You must only use positive `Integer` variables in a `Vars`.
91-
This implementation assumes that the user only provides positive `Integer` variables; the `Integer` -1, for example, is sometimes used to represent a `Rational` number.
92-
93101
## Example
94102

95103
```haskell
96104
exampleFunction :: (ObjectiveFunction, [PolyConstraint])
97105
exampleFunction =
98106
(
99-
Max [(1, 3), (2, 5)], -- 3x1 + 5x2
107+
Max {objective = Map.fromList [(1, 3), (2, 5)]}, -- 3x1 + 5x2
100108
[
101-
LEQ [(1, 3), (2, 1)] 15, -- 3x1 + x2 <= 15
102-
LEQ [(1, 1), (2, 1)] 7, -- x1 + x2 <= 7
103-
LEQ [(2, 1)] 4, -- x2 <= 4
104-
LEQ [(1, -1), (2, 2)] 6 -- -x1 + 2x2 <= 6
109+
LEQ {lhs = Map.fromList [(1, 3), (2, 1)], rhs = 15}, -- 3x1 + x2 <= 15
110+
LEQ {lhs = Map.fromList [(1, 1), (2, 1)], rhs = 7}, -- x1 + x2 <= 7
111+
LEQ {lhs = Map.fromList [(2, 1)], rhs = 4}, -- x2 <= 4
112+
LEQ {lhs = Map.fromList [(1, -1), (2, 2)], rhs = 6} -- -x1 + 2x2 <= 6
105113
]
106114
)
107115

@@ -111,13 +119,15 @@ twoPhaseSimplex (fst exampleFunction) (snd exampleFunction)
111119
The result of the call above is:
112120

113121
```haskell
114-
Just
115-
(7, -- Integer representing objective function
116-
[
117-
(7,29 % 1), -- Value for variable 7, so max(3x1 + 5x2) = 29.
118-
(1,3 % 1), -- Value for variable 1, so x1 = 3
119-
(2,4 % 1) -- Value for variable 2, so x2 = 4
120-
]
122+
Just
123+
(Result
124+
{ objectiveVar = 7 -- Integer representing objective function
125+
, varValMap = M.fromList
126+
[ (7, 29) -- Value for variable 7, so max(3x1 + 5x2) = 29.
127+
, (1, 3) -- Value for variable 1, so x1 = 3
128+
, (2, 4) -- Value for variable 2, so x2 = 4
129+
]
130+
}
121131
)
122132
```
123133

src/Linear/Simplex/Types.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ data TableauRow = TableauRow
9898
-- Each entry in the map is a row.
9999
type Tableau = M.Map Var TableauRow
100100

101-
-- | Values for a 'DictEntry'.
101+
-- | Values for a 'Dict'.
102102
data DictValue = DictValue
103103
{ varMapSum :: VarLitMapSum
104104
, constant :: SimplexNum

0 commit comments

Comments
 (0)