{"id":30852698,"url":"https://github.com/rasheedja/simplex-method","last_synced_at":"2025-10-18T03:44:12.572Z","repository":{"id":45734461,"uuid":"307819939","full_name":"rasheedja/simplex-method","owner":"rasheedja","description":"Implementation of the two-phase simplex method in exact rational arithmetic.","archived":false,"fork":false,"pushed_at":"2025-07-03T16:14:01.000Z","size":281,"stargazers_count":6,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-03T17:26:57.250Z","etag":null,"topics":["bsd-3-clause","haskell","linear-programming","math","mathematics","maths","optimisation","optimization","simplex-method"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rasheedja.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-10-27T20:28:07.000Z","updated_at":"2024-06-15T11:24:06.000Z","dependencies_parsed_at":"2022-08-28T17:01:42.615Z","dependency_job_id":"925fa0d8-0e8d-4e64-a11a-2378bd11f5cc","html_url":"https://github.com/rasheedja/simplex-method","commit_stats":{"total_commits":87,"total_committers":1,"mean_commits":87.0,"dds":0.0,"last_synced_commit":"72d536a84b50e32c26028a8f5f5071427dec7d74"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rasheedja/simplex-method","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasheedja%2Fsimplex-method","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasheedja%2Fsimplex-method/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasheedja%2Fsimplex-method/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasheedja%2Fsimplex-method/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rasheedja","download_url":"https://codeload.github.com/rasheedja/simplex-method/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasheedja%2Fsimplex-method/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274010104,"owners_count":25206764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bsd-3-clause","haskell","linear-programming","math","mathematics","maths","optimisation","optimization","simplex-method"],"created_at":"2025-09-07T08:07:16.647Z","updated_at":"2025-10-18T03:44:07.523Z","avatar_url":"https://github.com/rasheedja.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# simplex-method\n\n`simplex-method` is a Haskell library that implements the two-phase [simplex method](https://en.wikipedia.org/wiki/Simplex_algorithm) in exact rational arithmetic.\n\n## Quick Overview\n\nThe `Linear.Simplex.Solver.TwoPhase` module contain both phases of the two-phase simplex method.\n\n### Phase One\n\nPhase one is implemented by `findFeasibleSolution`:\n\n```haskell\nfindFeasibleSolution :: (MonadIO m, MonadLogger m) =\u003e [PolyConstraint] -\u003e m (Maybe FeasibleSystem)\n```\n\n`findFeasibleSolution` takes a list of `PolyConstraint`s.\nThe `PolyConstraint` type, as well as other custom types required by this library, are defined in the `Linear.Simplex.Types` module.\n`PolyConstraint` is defined as:\n\n```haskell\ndata PolyConstraint\n  = LEQ {lhs :: VarLitMapSum, rhs :: SimplexNum}\n  | GEQ {lhs :: VarLitMapSum, rhs :: SimplexNum}\n  | EQ {lhs :: VarLitMapSum, rhs :: SimplexNum}\n  deriving (Show, Read, Eq, Generic)\n```\n\n`SimplexNum` is an alias for `Rational`, and `VarLitMapSum` is an alias for `VarLitMap`, which is an alias for `Map Var SimplexNum`.\n`Var` is an alias of `Int`.\n\nA `VarLitMapSum` is read as `Integer` variables mapped to their `Rational` coefficients, with an implicit `+` between each entry.\nFor example: `Map.fromList [(1, 2), (2, (-3)), (1, 3)]` is equivalent to `(2x1 + (-3x2) + 3x1)`.\n\nAnd a `PolyConstraint` is an inequality/equality where the LHS is a `VarLitMapSum` and the RHS is a `Rational`.\nFor example: `LEQ (Map.fromList [(1, 2), (2, (-3)), (1, 3)] 60)` is equivalent to `(2x1 + (-3x2) + 3x1) \u003c= 60`.\n\nPassing a `[PolyConstraint]` to `findFeasibleSolution` will return a `FeasibleSystem` if a feasible solution exists:\n\n```haskell\ndata FeasibleSystem = FeasibleSystem\n  { dict :: Dict\n  , slackVars :: [Var]\n  , artificialVars :: [Var]\n  , objectiveVar :: Var\n  }\n  deriving (Show, Read, Eq, Generic)\n```\n\n```haskell\ntype Dict = M.Map Var DictValue\n\ndata DictValue = DictValue\n  { varMapSum :: VarLitMapSum\n  , constant :: SimplexNum\n  }\n  deriving (Show, Read, Eq, Generic)\n```\n\n`Dict` can be thought of as a set of equations, where the key represents a basic variable on the LHS of the equation\nthat is equal to the RHS represented as a `DictValue` value.\n\n### Phase Two\n\n`optimizeFeasibleSystem` performs phase two of the simplex method, and has the type:\n\n```haskell\n\noptimizeFeasibleSystem :: (MonadIO m, MonadLogger m) =\u003e ObjectiveFunction -\u003e FeasibleSystem -\u003e m (Maybe Result)\n\ndata ObjectiveFunction = Max {objective :: VarLitMapSum} | Min {objective :: VarLitMapSum}\n\ndata Result = Result\n  { objectiveVar :: Var\n  , varValMap :: VarLitMap\n  }\n  deriving (Show, Read, Eq, Generic)\n```\n\nWe give `optimizeFeasibleSystem` an `ObjectiveFunction` along with a `FeasibleSystem`.\n\n### Two-Phase Simplex\n\n`twoPhaseSimplex` performs both phases of the simplex method.\nIt has the type:\n\n```haskell\ntwoPhaseSimplex :: (MonadIO m, MonadLogger m) =\u003e ObjectiveFunction -\u003e [PolyConstraint] -\u003e m (Maybe Result)\n```\n\n### Extracting Results\n\nThe 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.\n\n```haskell\ndictionaryFormToTableau :: Dict -\u003e Tableau\n```\n\nThere are similar functions for `DictionaryForm` as well as other custom types in the module `Linear.Simplex.Util`.\n\n## Example\n\n```haskell\nexampleFunction :: (ObjectiveFunction, [PolyConstraint])\nexampleFunction =\n  (\n    Max {objective = Map.fromList [(1, 3), (2, 5)]},      -- 3x1 + 5x2\n    [\n      LEQ {lhs = Map.fromList [(1, 3), (2, 1)], rhs = 15}, -- 3x1 + x2 \u003c= 15 \n      LEQ {lhs = Map.fromList [(1, 1), (2, 1)], rhs = 7},  -- x1 + x2 \u003c= 7\n      LEQ {lhs = Map.fromList [(2, 1)], rhs = 4},          -- x2 \u003c= 4\n      LEQ {lhs = Map.fromList [(1, -1), (2, 2)], rhs = 6}  -- -x1 + 2x2 \u003c= 6\n    ]\n  )\n\ntwoPhaseSimplex (fst exampleFunction) (snd exampleFunction)\n```\n\nThe result of the call above is:\n\n```haskell\nJust \n  (Result\n    { objectiveVar = 7 -- Integer representing objective function\n    , varValMap = Map.fromList  \n      [ (7, 29) -- Value for variable 7, so max(3x1 + 5x2) = 29.\n      , (1, 3) -- Value for variable 1, so x1 = 3 \n      , (2, 4) -- Value for variable 2, so x2 = 4\n      ]\n    }\n  )\n```\n\nThere are many more examples in test/TestFunctions.hs.\nYou may use `prettyShowVarConstMap`, `prettyShowPolyConstraint`, and `prettyShowObjectiveFunction` to convert these tests into a more human-readable format.\n\n## Issues\n\nPlease share any bugs you find [here](https://github.com/rasheedja/simplex-haskell/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frasheedja%2Fsimplex-method","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frasheedja%2Fsimplex-method","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frasheedja%2Fsimplex-method/lists"}