Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

**Run tests:**
```julia
using Pkg; Pkg.test("TableauSimplex")
```
Or from the Julia REPL package manager (`]`):
```
test TableauSimplex
```

**Load the package interactively:**
```julia
using Pkg; Pkg.activate("."); using TableauSimplex
```

**Run an example script:**
```bash
julia --project examples/flights.jl
julia --project examples/network.jl
```

There is no linter or formatter configured for this project.

## Architecture

All logic lives in two files: `src/TableauSimplex.jl` (module + exports) and `src/functions.jl` (all implementations).

### Core data structure

`Tableau{T <: Number}` holds three fields:
- `table::Matrix{T}` — the full tableau matrix. Row 1 is the objective row (stores negated reduced costs in columns 1..n and the negated objective value in the last column). Rows 2..end are constraint rows. The last column of every row is the RHS.
- `basis::Vector{Int}` — length-`m` vector of column indices currently in the basis (one per constraint row).
- `varnames::Vector{String}` — human-readable names for all `n` decision+slack variables.

The type parameter `T` propagates through all operations. Using `Rational{Int}` gives exact arithmetic; `Float64` is the default for numeric input.

### Tableau construction

`tableau(A, b, c)` builds a standard-form LP tableau by appending an identity block for slack variables. The basis is initialized to the slack variable indices `n+1:n+m`.

You can also construct a `Tableau` directly, as in the examples, when a non-standard initial basis or variable naming is needed.

### Mutating vs. copying conventions

Every algorithm has two variants:
- `func!(Tab, ...)` — mutates `Tab` in place and returns it.
- `func(Tab, ...)` — copies `Tab` first via `copy(Tab)`, then calls `func!` on the copy.

This applies to `simplex`/`simplex!`, `dualsimplex`/`dualsimplex!`, `simplexpivot`/`simplexpivot!`, `dualsimplexpivot`/`dualsimplexpivot!`, and `pivot`/`pivot!`.

### Algorithms

**Primal simplex** (`simplex!`): Dantzig's rule (most-negative reduced cost) for entering variable, minimum-ratio test for leaving variable. Detects unboundedness.

**Dual simplex** (`dualsimplex!`): Most-negative RHS for leaving variable, minimum-ratio test on the objective row for entering variable. Detects infeasibility.

**Integer programming** (`solveip`): Solves the LP relaxation, then iteratively adds Gomory cuts (`addGomorycuts`) for fractional basic variables and re-optimizes with dual simplex until all RHS values are integer. Randomly selects among fractional variables each iteration; not deterministic. Accepts either `(Tab)` or `(A, b, c)` (which requires integer `A` and `b`).

### Display

The global `__show_mode__` (`:compact` by default, can be set to `:full`) controls the `show` method. In compact mode, columns for basic variables are suppressed — only non-basic variable columns are printed, alongside the RHS.

`clean!(Tab)` re-pivots each basic variable's column back to a unit vector; useful after manually constructing or splicing a tableau to restore canonical form.

### Utility

`num2string` pretty-prints numbers: zero becomes `""`, `Rational{Int}` prints as `p/q`, and other types use Julia's default string conversion.