Skip to main content

simplex_trace/
lib.rs

1//! # simplex-trace
2//!
3//! A simplex solver for linear programs that uses **exact rational arithmetic** and records
4//! **every step** (tableaus, ratio tests, pivots, phase changes) as plain data, so a teaching
5//! tool or UI can replay the method exactly as it is done by hand.
6//!
7//! Supported methods: primal simplex, Big-M (with a symbolic `M`), two-phase and dual simplex.
8//! Variables are non-negative unless declared free or non-positive (see [`Sign`]). Every
9//! optimal solution includes a [`Sensitivity`] analysis
10//! (shadow prices, reduced costs and ranges), and [`reoptimize`] repairs it with dual simplex
11//! pivots after constraints are added, instead of solving again.
12//!
13//! With the **`serde`** feature, [`Problem`], [`Solution`], [`Trace`] and every [`Step`] can be
14//! (de)serialized, e.g. to JSON for a web front end. Numbers are exact strings such as `"3/2"`.
15//!
16//! ```
17//! use simplex_trace::{solve, Method, Options, Problem, Relation, Status, ratio};
18//!
19//! // min 4x1 + x2  s.t.  3x1 + x2 = 3,  4x1 + 3x2 >= 6,  x1 + 2x2 <= 4
20//! let problem = Problem::minimize([4, 1])
21//!     .subject_to([3, 1], Relation::Eq, 3)
22//!     .subject_to([4, 3], Relation::Ge, 6)
23//!     .subject_to([1, 2], Relation::Le, 4);
24//!
25//! let solution = solve(&problem, Method::TwoPhase, &Options::default()).unwrap();
26//! assert_eq!(
27//!     solution.status,
28//!     Status::Optimal { objective: ratio(17, 5), values: vec![ratio(2, 5), ratio(9, 5)] }
29//! );
30//!
31//! // Every tableau and pivot is available for display or replay.
32//! for snapshot in solution.trace.tableaus() {
33//!     println!("{snapshot}");
34//! }
35//! ```
36
37#![forbid(unsafe_code)]
38
39mod error;
40mod num;
41mod problem;
42mod rational;
43mod sensitivity;
44mod solver;
45mod trace;
46
47pub use error::Error;
48pub use num::{Coef, IntoRational, ratio};
49pub use problem::{Constraint, Problem, Relation, Sense, Sign};
50pub use rational::{ParseRationalError, Rational};
51pub use sensitivity::{ConstraintSensitivity, Interval, Sensitivity, Source, VariableSensitivity};
52pub use solver::{Method, Options, PivotRule, Solution, Status, reoptimize, solve};
53pub use trace::{DualRatioTest, NamedValue, Phase, RatioTest, Snapshot, Step, Termination, Trace};
54
55// Compile the Rust examples of the README as doctests, so it cannot drift from the API.
56#[cfg(doctest)]
57#[doc = include_str!("../README.md")]
58struct ReadmeDoctests;