Why Linear Programming Matters
A factory can choose production quantities while respecting machine hours, material limits, and demand caps. If each constraint and the total contribution are linear in the quantities, the model is a linear program, or LP. The same structure appears in transportation, blending, network flows, and many continuous planning models.
Linear programming optimizes continuous variables. It does not make a quantity integral merely because the input coefficients are integers. Its power comes from the geometry of a polyhedron and from dual certificates that can prove an optimum, not just suggest a good point.
This lesson implements primal tableau simplex with deterministic anti-cycling choices and exact rational arithmetic on small integer models. It also explains how revised simplex performs the same basis logic through linear solves, and how interior-point methods approach optimality using primal–dual equations rather than a vertex walk. The code is deliberately a feasible-start Phase II solver: it accepts nonnegative right-hand sides and does not implement Phase I. General feasibility handling is explained separately rather than mislabeled as an infeasibility test.
An LP optimizes a linear objective over linear constraints; simplex improves a feasible basic solution by exchanging one basis variable at a time. A minimum-ratio pivot preserves feasibility, reduced costs identify improvement, and matching feasible primal and dual values certify optimality. Revised simplex changes the linear algebra representation, while interior-point methods follow a different path toward the same primal–dual conditions.
Core Concepts and Terminology
Use the maximization convention
$$\max_{\mathbf x}\ \mathbf c^{\mathsf T}\mathbf x\qquad\text{subject to }A\mathbf x\leq\mathbf b,\quad\mathbf x\geq\mathbf0.$$
There are $n$ original decision variables and $m$ inequality rows. Our implementation requires integer data, $\mathbf b\geq\mathbf0$, and explicit nonnegativity of every decision variable. The origin is therefore feasible. Negative coefficients in $A$ or $\mathbf c$ are allowed.
Introduce nonnegative slack variables $\mathbf s=\mathbf b-A\mathbf x$, and collect $\mathbf w=(\mathbf x,\mathbf s)$, $M=[A\ I]$, and $\overline{\mathbf c}=(\mathbf c,\mathbf0)$. The standard-form equations are
$$M\mathbf w=\mathbf b,\qquad\mathbf w\geq\mathbf0,\qquad z=\overline{\mathbf c}^{\mathsf T}\mathbf w.$$
A basis is a choice of $m$ linearly independent columns of $M$. Write the corresponding square matrix as $B$. Set nonbasic variables to zero and solve $\mathbf w_B=B^{-1}\mathbf b$. If these basic values are nonnegative, this gives a basic feasible solution. The initial basis consists of the slack columns, so $B=I$ and $\mathbf w_B=\mathbf b$.
A basic variable can equal zero. Such a solution is degenerate: a pivot may change the basis without moving the decision vector or increasing its objective. Bases and geometric vertices are related but are not interchangeable objects.
Tableau convention. Constraint rows store $D=B^{-1}M$ and right-hand side $\mathbf h=B^{-1}\mathbf b$. The objective row represents
$$z+\sum_{j=1}^{n+m}p_jw_j=z_0,\qquad \mathbf p^{\mathsf T}=\mathbf y^{\mathsf T}M-\overline{\mathbf c}^{\mathsf T},\qquad B^{\mathsf T}\mathbf y=\overline{\mathbf c}_B.$$
Thus $p_j$ is minus the reduced cost $r_j=\overline c_j-M_j^{\mathsf T}\mathbf y$. A negative objective-row coefficient means that increasing that nonbasic variable improves a maximization objective. Initially the bottom row is $(-\mathbf c,\mathbf0\mid0)$. Its right-hand side always stores the current objective, with no sign reversal.
The dual of the original maximization model is
$$\min_{\mathbf y}\ \mathbf b^{\mathsf T}\mathbf y\qquad\text{subject to }A^{\mathsf T}\mathbf y\geq\mathbf c,\quad\mathbf y\geq\mathbf0.$$
For feasible $\mathbf x,\mathbf y$, weak duality gives $\mathbf c^{\mathsf T}\mathbf x\leq\mathbf b^{\mathsf T}\mathbf y$. Equality proves both are optimal. In an optimal tableau, the objective-row coefficients in the original slack columns give this $\mathbf y$.
An unbounded maximization LP has feasible points with arbitrarily large objective. A certificate is a feasible point $\mathbf x$ and a direction $\mathbf d\geq\mathbf0$ with $A\mathbf d\leq\mathbf0$ and $\mathbf c^{\mathsf T}\mathbf d\gt0$. Then $\mathbf x+t\mathbf d$ is feasible and improves without limit for $t\geq0$. An infeasible LP has no feasible point; this is a different condition. Every model accepted by this solver is already feasible, so it never returns INFEASIBLE.
For broader geometry, standard-form transformations, and duality, see Goemans's MIT linear-programming notes.
| Term | Bounded example | Role |
|---|---|---|
| Decision variables | $x_1,x_2\geq0$ | Continuous quantities to choose |
| Objective | $\max(3x_1+2x_2)$ | Linear quantity to improve |
| Constraints | $x_1+x_2\leq4$, $x_1\leq2$, $x_2\leq3$ | Feasible polygon boundaries |
| Slack | $s_1=4-x_1-x_2$ | Nonnegative unused capacity of one inequality |
| Initial basis | $(s_1,s_2,s_3)$ with values $(4,2,3)$ | Feasible origin represented algebraically |
| Reduced cost | Initial $r_{x_1}=3$ | Objective gain per unit of an entering nonbasic variable |
| Entering / leaving | Pivot $1$: $x_1$ enters, $s_2$ leaves | Replaces one basis column |
| Eligible ratio | $\min(4/1,2/1)=2$ for pivot $1$ | Largest feasible movement along the chosen direction |
| Degeneracy | An eligible minimum ratio can be $0$ | Basis changes without objective improvement |
| Dual certificate | $\mathbf y=(2,1,0)$ | Proves the upper bound $z\leq10$ |
| Unbounded ray | For $x_1-x_2\leq1$, $\mathbf c=(1,1)$: $\mathbf d=(1,1)$ | Feasible direction with positive objective growth |
How Linear Programming Works, Step by Step
The implemented algorithm maintains a feasible basis and applies Bland's rule. Variable IDs put original variables first, then slacks; the code uses zero-based IDs, while the sample output uses names such as x1 and s1.
- Validate the supported model. Check dimensions, integer coefficients, nonnegative right-hand sides, and the pivot cap. Build constraint rows $[A\ I\mid\mathbf b]$ and the objective row $[-\mathbf c\ \mathbf0\mid0]$. Record the initial basis and point.
- Test optimality. Scan all variable columns in increasing ID order. If no objective coefficient is negative, return OPTIMAL and read the dual vector from the slack columns.
- Choose the entering variable. Select the smallest variable ID $e$ with $p_e\lt0$. Basic columns have objective coefficient zero in exact arithmetic.
- Find the first blocking constraint. Let $\mathbf d=D_e$ be the entering column. Increasing the entering variable by $\theta$ changes basic values to $\mathbf h-\theta\mathbf d$. Only rows with $d_i\gt0$ impose upper limits. Minimize $h_i/d_i$ over those rows. If ratios tie, choose the row whose current basic variable has the smallest ID; row position is not the tie-break.
- Recognize unboundedness if no row blocks. If all $d_i\leq0$, set the entering component of a standard-form direction to $1$, basic components to $-d_i$, and all other nonbasic components to zero. Return its original-variable part as an exact improving ray.
- Check the pivot cap. If a pivot is required but the permitted count has been reached, return PIVOT_LIMIT. Optimality and unboundedness checks take precedence because neither requires another pivot. A zero cap can therefore still return a certificate.
- Pivot. Divide the leaving row by its positive pivot entry. Subtract suitable multiples of that normalized row from every other row, including the objective, so the entering column becomes a unit basis column. Replace the leaving variable in the basis list.
- Record and repeat. Store the entire tableau, original-variable point, current objective, entering and leaving IDs, and ratio. The row numbered $k$ is the state after $k$ completed pivots; its entering, leaving, and ratio fields describe the pivot into that state. Initial fields are NONE and zero.
Bland's entering rule and leaving-variable tie-break prevent cycling in exact arithmetic. They do not require the largest objective gain or the largest reduced cost. The solver records degenerate pivots even when their ratio is zero.
Revised simplex: the same decisions through solves. A large implementation need not form the whole transformed matrix $B^{-1}M$. Maintain the original sparse matrix and a factorization of $B$. Solve $B\mathbf w_B=\mathbf b$ for the basic values and $B^{\mathsf T}\mathbf y=\overline{\mathbf c}_B$ for dual multipliers. Price candidate columns using $r_j=\overline c_j-M_j^{\mathsf T}\mathbf y$. For the chosen entering column, solve $B\mathbf d=M_e$ and perform the same ratio test. Update the basis factorization, with periodic refactorization. Explicitly computing and repeatedly multiplying a stored inverse is generally a poor numerical implementation strategy. Revised simplex is a representation and linear-algebra improvement, not a new optimality criterion.
Interior-point overview. In the standard-form notation above, let the dual slack be $\mathbf q=M^{\mathsf T}\mathbf y-\overline{\mathbf c}$. Primal–dual optimality requires
$$M\mathbf w=\mathbf b,\qquad M^{\mathsf T}\mathbf y-\mathbf q=\overline{\mathbf c},\qquad \mathbf w,\mathbf q\geq\mathbf0,\qquad w_jq_j=0.$$
A central-path approach replaces complementarity by $w_jq_j=\mu$ with $\mu\gt0$, maintaining positive primal variables and dual slacks where the relevant strict-feasibility assumptions hold. Newton steps approximately solve these coupled equations; step control preserves positivity and the target $\mu$ decreases toward zero. These steps generally move through the relative interior rather than visiting adjacent vertices. Practical methods also handle infeasible starting points, scaling, and certificate detection. This is a conceptual overview, not an additional solver hidden inside the code. Boyd and Vandenberghe's interior-point slides develop the barrier and primal–dual viewpoint.
flowchart TD
A["Validate small integer model and nonnegative RHS"] --> B["Build slack basis and exact tableau; record origin"]
B --> C{"Any negative objective coefficient?"}
C -->|No| Z["Return OPTIMAL and exact dual certificate"]
C -->|Yes| D["Smallest-ID negative coefficient enters"]
D --> E["Compute ratios only where entering-column entry is positive"]
E --> F{"Any eligible leaving row?"}
F -->|No| Y["Return UNBOUNDED with feasible point and improving ray"]
F -->|Yes| G["Minimum ratio; tie by smallest basic-variable ID"]
G --> H{"Pivot cap reached?"}
H -->|Yes| X["Return PIVOT_LIMIT with current feasible point"]
H -->|No| I["Normalize pivot row; eliminate column in every other row"]
I --> J["Replace basis variable; record tableau and objective"]
J --> C
Worked Example with a Full Trace
Consider
$$\max z=3x_1+2x_2,\qquad x_1+x_2\leq4,\quad x_1\leq2,\quad x_2\leq3,\quad x_1,x_2\geq0.$$
Add slacks $s_1,s_2,s_3$ in that row order. The tableau columns below are $(x_1,x_2,s_1,s_2,s_3,\mathrm{rhs})$, with the objective equation last. All entries are exact integers in this example.
Initial state. Basis $(s_1,s_2,s_3)$ has values $(4,2,3)$; original point is $(0,0)$ and $z=0$:
$$T_0=\begin{pmatrix}1&1&1&0&0&4\\1&0&0&1&0&2\\0&1&0&0&1&3\\-3&-2&0&0&0&0\end{pmatrix}.$$
Pivot 1: enter $x_1$, leave $s_2$. The first negative objective coefficient is $-3$, so Bland's rule selects $x_1$. Its constraint column is $(1,1,0)$. Ratios are $4/1=4$ in the $s_1$ row and $2/1=2$ in the $s_2$ row; the zero entry in the $s_3$ row is ineligible. Thus $\theta=2$ and $s_2$ leaves.
The pivot entry is already $1$. Keep the normalized second row; subtract it from the first row; leave the third row unchanged; and add three copies of it to the objective row:
$$T_1=\begin{pmatrix}0&1&1&-1&0&2\\1&0&0&1&0&2\\0&1&0&0&1&3\\0&-2&0&3&0&6\end{pmatrix}.$$
Basis $(s_1,x_1,s_3)$ now has values $(2,2,3)$, so $(x_1,x_2)=(2,0)$. Objective gain is $r_{x_1}\theta=3\cdot2=6$.
Pivot 2: enter $x_2$, leave $s_1$. The only negative objective coefficient is $-2$. The entering column is $(1,0,1)$, and basic values are $(2,2,3)$. Eligible ratios are $2/1=2$ and $3/1=3$; the middle row is skipped. Thus $\theta=2$ and $s_1$ leaves.
The first row is already normalized. Leave the second row unchanged, subtract the first row from the third, and add two copies of the first row to the objective:
$$T_2=\begin{pmatrix}0&1&1&-1&0&2\\1&0&0&1&0&2\\0&0&-1&1&1&1\\0&0&2&1&0&10\end{pmatrix}.$$
Basis $(x_2,x_1,s_3)$ has values $(2,2,1)$. The original point is $(2,2)$, slacks are $(0,0,1)$, and the objective is $6+2\cdot2=10$. No objective coefficient is negative, so the solver returns OPTIMAL.
Independent certificate. The slack-column objective coefficients give $\mathbf y=(2,1,0)$. They are nonnegative and
$$A^{\mathsf T}\mathbf y=(3,2)=\mathbf c,\qquad \mathbf b^{\mathsf T}\mathbf y=4\cdot2+2\cdot1+3\cdot0=10=\mathbf c^{\mathsf T}(2,2).$$
Primal feasibility, dual feasibility, and equality of objectives prove optimality without trusting the pivot history. The certificate is not just a small change in objective or a claim of convergence.
The programs also run three boundary cases. A cap of $1$ on this bounded model returns PIVOT_LIMIT at $(2,0)$ with current value $6$. For $x_1-x_2\leq1$ and objective $x_1+x_2$, simplex reaches $(1,0)$ and returns UNBOUNDED with ray $(1,1)$: $A\mathbf d=0$ and $\mathbf c^{\mathsf T}\mathbf d=2$. For $\max x_1$ subject to $2x_1\leq3$, the exact optimum is $x_1=3/2$ with dual multiplier $1/2$; integer input does not imply an integer LP solution.
Trace It by Hand
Before pivot 2, predict what happens if the last right-hand side in the original bounded model changes from $3$ to $2$. The first pivot still produces basic values $(2,2,2)$ with basis $(s_1,x_1,s_3)$.
When $x_2$ enters, the eligible ratios are now tied: $2/1=2$ for $s_1$ and $2/1=2$ for $s_3$. Bland's rule chooses the smaller basic-variable ID, so $s_1$ leaves. The new point is still $(2,2)$ with objective $10$, and $s_3$ is a zero-valued basic variable. The solution is degenerate.
As a second check, keep the original model but cap pivots at zero. The initial tableau has a negative objective coefficient and a valid leaving row, so the result is PIVOT_LIMIT at the feasible origin, not OPTIMAL. A cap limits computation; it is not an optimality criterion.
Implementation in Python, C++, and Java
Each panel is a complete, independently runnable exact tableau solver for $\max\mathbf c^{\mathsf T}\mathbf x$ with $A\mathbf x\leq\mathbf b$ and $\mathbf x\geq0$. Its signature is simplex(A, b, c, pivot_cap), with a default cap in Python and C++; Java takes the cap explicitly. It accepts $0\leq m\leq3$ rows, $1\leq n\leq6$ variables, integer coefficients in $[-100,100]$, integer right-hand sides in $[0,100]$, and $0\leq\text{pivot cap}\leq2000$. All matrix rows must have length $n$. Python rejects booleans and nonintegers rather than silently converting them. C++ and Java use integer input types.
The nonnegative-RHS requirement gives an immediate feasible slack basis. A negative RHS is rejected as unsupported input, not diagnosed as infeasible. For example, $-x_1\leq-1$, $x_1\geq0$ is feasible, but needs a different start or Phase I and is outside this implementation. Zero rows and even zero inequality constraints are supported; nonnegativity of the decision variables still applies.
Rationals are normalized with positive denominators. Python uses Fraction and Java uses BigInteger. C++ uses a small rational helper backed by the GCC signed 128-bit integer extension, with checked arithmetic that throws on overflow instead of wrapping. The intentionally tiny row and coefficient limits keep simplex intermediates within that representation: tableau entries are ratios of matrix minors of order at most four, and the stated bounds allow a conservative intermediate bound below $10^{28}\lt2^{127}$. Do not raise those limits in C++ without a fresh bound or an arbitrary-precision rational type. Exact arithmetic here removes epsilon tests; it does not turn this dense teaching implementation into a large-scale LP solver.
Run Python 3 with python main.py. Compile the C++ panel using a GCC target with 128-bit integer support: g++ -std=c++17 main.cpp -o lp, then ./lp. Save Java as Main.java and run javac Main.java followed by java Main. No third-party library is needed. Values print as integers or reduced fractions, so there is no decimal formatting or hidden rounding difference.
The result contains a feasible original-variable point and its current objective for every accepted model. OPTIMAL also contains a dual certificate; UNBOUNDED contains an improving ray; PIVOT_LIMIT contains neither. Empty certificate fields print (). The current objective printed for an unbounded run is the value of its finite returned feasible point, not a finite optimum. Each history row owns a complete tableau and basis snapshot. Repeated variable names in different bases refer to the same fixed variable IDs.
The implementations use the same entering order, exact ratio comparisons, leaving-variable tie-break, terminal-check precedence, row-operation order, and pivot cap. They do not implement artificial variables, revised-simplex factorization updates, an interior-point algorithm, integer programming, presolve, or general variable bounds.
Expected standard output, identical in all three languages:
boundedk=0 basis=(s1,s2,s3) x=(0,0) z=0 enter=NONE leave=NONE theta=0k=1 basis=(s1,x1,s3) x=(2,0) z=6 enter=x1 leave=s2 theta=2k=2 basis=(x2,x1,s3) x=(2,2) z=10 enter=x2 leave=s1 theta=2status=OPTIMAL current_z=10 pivots=2 dual=(2,1,0) ray=()pivot-limitk=0 basis=(s1,s2,s3) x=(0,0) z=0 enter=NONE leave=NONE theta=0k=1 basis=(s1,x1,s3) x=(2,0) z=6 enter=x1 leave=s2 theta=2status=PIVOT_LIMIT current_z=6 pivots=1 dual=() ray=()unboundedk=0 basis=(s1) x=(0,0) z=0 enter=NONE leave=NONE theta=0k=1 basis=(x1) x=(1,0) z=1 enter=x1 leave=s1 theta=1status=UNBOUNDED current_z=1 pivots=1 dual=() ray=(1,1)fractionalk=0 basis=(s1) x=(0) z=0 enter=NONE leave=NONE theta=0k=1 basis=(x1) x=(3/2) z=3/2 enter=x1 leave=s1 theta=3/2status=OPTIMAL current_z=3/2 pivots=1 dual=(1/2) ray=()
Complexity, Correctness, and Invariants
Write $N=n+m$ for the total number of original and slack variables, and $P$ for the number of completed pivots. A dense tableau contains $(m+1)(N+1)$ rational entries. Construction, snapshots, and a full pivot each take $O((m+1)(N+1))$ rational work; entering scans take $O(N)$, and ratio scans use $O(m)$ exact comparisons and divisions.
The reference program therefore uses $O((P+1)(m+1)(N+1))$ rational operations and the same order of storage when it retains every tableau. Without history, working storage is $O((m+1)(N+1))$. The best case returns immediately after setup and an optimality or unboundedness scan, at $\Theta((m+1)(N+1))$ setup cost. There is no distribution-free “average pivot count.” For unrestricted dimensions, simplex has exponential worst-case pivot behavior; an anti-cycling rule gives finite termination, not a polynomial-time bound. A cap $K$ gives an upper bound $O((K+1)(m+1)(N+1))$ rational operations, while permitting an unfinished result.
For the deliberately tiny accepted dimensions, there are at most $\binom93=84$ candidate basis sets. Exact Bland pivots do not revisit a basis, so no more than $83$ pivots are needed before classification; the default cap of $100$ exceeds that bound. This small-model fact is not a general LP complexity result.
Rational field operations are not unit-cost operations on arbitrary-size input. Numerator and denominator growth, integer multiplication, division, and greatest-common-divisor reduction matter. Python and Java use arbitrary-precision arithmetic; the C++ helper uses the bounded, checked representation described above. Quoting only a count of tableau cells omits bit complexity.
Feasibility and equation invariant. Initially the tableau is the original slack system and the basic values are nonnegative. Suppose the current tableau represents the same equations with an identity basis, nonnegative basic RHS, and objective $z+\mathbf p^{\mathsf T}\mathbf w=z_0$. Increasing an entering nonbasic variable to $\theta$ makes basic values $h_i-\theta d_i$. The minimum eligible ratio is precisely the largest allowed step before some positive-direction row hits zero. All other basic values remain nonnegative.
Normalizing and eliminating are invertible row operations, so they preserve the feasible equality system and objective equation. The entering column becomes a unit column, the updated basis has the new feasible values, and the original-variable point extracted from it is feasible. Objective change is $(-p_e)\theta\geq0$. A zero ratio is permitted: feasibility is preserved even though the objective does not increase. Bland's rule supplies the separate anti-cycling argument.
Optimality certificate. When every $p_j\geq0$, the current objective equation bounds $z\leq z_0$ for every nonnegative feasible $\mathbf w$. Equivalently, $\mathbf p=M^{\mathsf T}\mathbf y-\overline{\mathbf c}\geq0$. Slack columns imply $\mathbf y\geq0$, and original columns imply $A^{\mathsf T}\mathbf y\geq\mathbf c$. The current basic point has $\mathbf c^{\mathsf T}\mathbf x=z_0=\mathbf b^{\mathsf T}\mathbf y$. Weak duality proves it is globally optimal.
Unboundedness certificate. With $p_e\lt0$ and no positive direction entry, the constructed standard-form direction has nonnegative components and satisfies $M\mathbf d_{\rm full}=0$. Its original-variable part obeys $\mathbf d\geq0$ and $A\mathbf d\leq0$, because the slack direction is also nonnegative. Moreover $\mathbf c^{\mathsf T}\mathbf d=-p_e\gt0$. The returned feasible point plus any nonnegative multiple of that direction is feasible and improves without limit.
These are exact certificates, not convergence heuristics. PIVOT_LIMIT establishes neither optimality nor unboundedness. The exact program also makes a meaningful distinction between a repeated objective value and a repeated basis.
Revised simplex cost. Dense basis solves take $O(m^2)$ after a factorization; a fresh dense factorization costs $O(m^3)$. Pricing all columns typically adds $O(mN)$ arithmetic, with sparse structure and pricing policies changing the practical cost. Sparse revised simplex retains the original matrix and basis factors rather than a full dense transformed tableau. Factor fill, stability, update strategy, and periodic refactorization are central engineering issues.
Interior-point cost and termination. Suitable path-following LP algorithms have polynomial complexity guarantees under their stated input and initialization assumptions. A practical primal–dual iteration is often dominated by a sparse linear-system factorization, not by scanning every neighboring vertex. In the standard-form central-path equations, the duality gap is
$$\mathbf b^{\mathsf T}\mathbf y-\overline{\mathbf c}^{\mathsf T}\mathbf w=\mathbf w^{\mathsf T}\mathbf q=N\mu$$
when primal and dual equations are satisfied and $w_jq_j=\mu$ for every component. Thus decreasing complementarity targets has a direct optimality meaning. Approximate implementations check primal residuals, dual residuals, and gap together; a small gap alone with infeasible vectors is insufficient. General infeasibility and unboundedness handling requires additional machinery, such as appropriate homogeneous formulations. An interior-point iterate need not be a vertex; crossover can construct a basis when that is desired.
| Method | Main algebra / per-iteration work | Working storage excluding history | Important limit |
|---|---|---|---|
| Dense tableau simplex | $O(mN)$ field operations for a typical pivot, with $m+1,N+1$ covering empty-row cases | $O((m+1)(N+1))$ | Clear basis trace; may take exponentially many pivots in general |
| Revised simplex | Basis solves, factor updates, and pricing; dense refactorization $O(m^3)$ | Original matrix plus basis factors and work vectors | Avoids a full transformed tableau; sparse factor fill and stability matter |
| Primal–dual interior point | Newton system assembly and factorization; depends on sparsity and formulation | Matrix factors plus primal/dual vectors | Polynomial bounds for suitable algorithms; numerical residual and gap tests |
| Vertex enumeration | Up to $\binom Nm$ candidate bases and a solve per candidate | Matrix plus one candidate or a stored list | Useful independent oracle on tiny LPs; combinatorial explosion |
| This exact teaching solver | $O((P+1)(m+1)(N+1))$ rational operations | $O((P+1)(m+1)(N+1))$ including full history | At most three inequality rows, six decisions, bounded integer data, feasible slack start |
The invariant is an equivalent canonical tableau with nonnegative basic values; the minimum-ratio pivot preserves it even when the objective stays unchanged. Nonnegative final objective coefficients yield a feasible dual with the same value as the primal point, while an unblocked improving column yields an explicit feasible ray. These certificates prove the terminal status; a pivot cap proves neither.
Variants, Pitfalls, and Optimizations
Feasible start versus general feasibility. A negative RHS does not mean the LP is infeasible. A general two-phase method first constructs an auxiliary problem with artificial variables, minimizing their sum. A positive auxiliary optimum proves the original equalities cannot be satisfied with the required nonnegativity. A zero optimum permits Phase II after artificial variables are removed, including pivoting out zero-valued artificial basics or deleting redundant rows when appropriate. Restore and canonicalize the original objective before continuing. Multiplying a constraint by $-1$ reverses its inequality direction; adding a slack with the wrong sign changes the problem. Cornell's LP course, Lectures 6–10 covers this transition and general forms.
Respect the tableau sign convention. This maximization solver enters a column with a negative bottom-row coefficient because the row stores minus reduced costs. A different book can use the opposite sign convention. Derive the objective equation before copying a pivot rule. The RHS here is the actual current objective, not its negative.
Use the correct ratio test and tie-break. Ratios are considered only for strictly positive entering-column entries, and the minimum preserves feasibility. Zero ratios are valid degenerate pivots, not a reason to divide by zero or discard the row. Ties are broken by the basic variable's fixed ID, which can differ from the row number after pivots. Choosing the largest ratio can move to a point with a larger objective that violates the constraints.
Degeneracy, cycling, and multiple optima are different. A zero basic variable signals degeneracy. Cycling concerns repeated bases under a pivot rule. Multiple optima concern distinct feasible points with the same optimal value. At an optimal tableau, a zero reduced-cost nonbasic column can indicate an alternative optimal movement, but degeneracy may make a particular zero-cost pivot fail to produce a different point. Do not declare termination merely because one pivot leaves the objective unchanged. Exact Bland pivots prevent cycling here; numerical solvers also need tolerance and stability policies.
LP relaxation is not integer programming. The fractional sample has integer inputs and an optimum $3/2$. If a production variable must be an integer, the LP is only a relaxation unless special structure supplies integrality. Rounding a fractional solution can violate constraints or lose optimality. Network incidence structures can have integrality properties under suitable hypotheses; arbitrary integer matrices do not.
Numerical and modeling practice. Large solvers ordinarily use floating-point sparse factorizations, scaling, presolve, and refactorization. Near-zero reduced costs or pivot entries then need numerical policies, and reported primal/dual residuals must be checked. Exact rational arithmetic is valuable for small demonstrations and independent verification, while bit growth can make it expensive at scale. Polynomial bit complexity and strongly polynomial arithmetic-operation bounds are different notions; coefficient bit length matters in the former.
Variable lower bounds can be shifted, free variables split into a difference of nonnegative variables, and equalities handled in standard form. These transformations change dimensions and may change the feasible starting basis. The reference solver does not silently perform them. Revised simplex warm starts can reuse a basis after suitable model changes, while interior-point solutions may require crossover to obtain a useful basic representation.
Keep objective signs, inequality directions, and variable bounds explicit. Preserve feasibility with the minimum eligible ratio, allow zero-ratio degenerate pivots, and apply Bland's leaving-variable tie-break rather than a row-index shortcut. A negative RHS is not an infeasibility certificate, a larger infeasible objective is not progress, and an integer-data LP can have a fractional optimum.
Practice Problems and Real-World Use
Start by reproducing the bounded primal and its dual certificate, then verify the unbounded ray without using the tableau. These checks separate optimization claims from implementation details. For larger models, formulate units and bounds carefully and inspect solver status, primal/dual residuals, and certificate information before using the result.
The exercises below connect vertex geometry, exact linear algebra, and the practical representations introduced in the lesson. Keep continuous and integer versions of a model distinct.
| Exercise or application | Concrete task / expected check | Main idea | Difficulty |
|---|---|---|---|
| Resource-allocation example | Reproduce $(2,2)$ with objective $10$ and dual $(2,1,0)$ | Basis pivots and exact optimality certificate | Beginner |
| Fractional capacity | Solve $2x\leq3$, $\max x$, and explain $x=3/2$ | LP variables are continuous | Beginner |
| Unbounded-ray audit | For $x_1-x_2\leq1$, verify direction $(1,1)$ preserves feasibility and gains $2$ per unit | Exact unboundedness certificate | Intermediate |
| Degenerate ratio tie | Change the third RHS to $2$ and apply the leaving-variable ID tie-break | Degeneracy versus row order | Intermediate |
| Tiny revised simplex | Reconstruct each sample tableau using basis solves and reduced costs | Representation-independent basis logic | Advanced |
| Transportation or min-cost flow | Formulate conservation and capacity constraints; distinguish structural integrality from arbitrary LPs | Sparse models and network structure | Intermediate |
| Phase I extension | Add artificial-variable handling and an exact infeasibility certificate for unsupported starts | Feasibility is a separate optimization problem | Advanced |
| Interior-point residual lab | On a strictly feasible tiny LP, track primal residual, dual residual, and complementarity gap together | Central path and numerical optimality measures | Advanced |