Skip to content
Open
Show file tree
Hide file tree
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
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ make cli # builds target/release/pred

See the [Getting Started](https://codingthrust.github.io/problem-reductions/getting-started.html) guide for usage examples, the reduction workflow, and [CLI usage](https://codingthrust.github.io/problem-reductions/cli.html).

Try a model directly from the CLI:

```bash
# Show the Consecutive Block Minimization model (alias: CBM)
pred show CBM

# Create and solve a small CBM instance (currently with brute-force)
pred create CBM --matrix '[[true,false,true],[false,true,true]]' --bound-k 2 \
| pred solve - --solver brute-force
```

## MCP Server (AI Integration)

The `pred` CLI includes a built-in [MCP](https://modelcontextprotocol.io/) server for AI assistant integration (Claude Code, Cursor, Windsurf, OpenCode, etc.).
Expand Down
35 changes: 35 additions & 0 deletions docs/paper/reductions.typ
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"PartitionIntoTriangles": [Partition Into Triangles],
"FlowShopScheduling": [Flow Shop Scheduling],
"MinimumTardinessSequencing": [Minimum Tardiness Sequencing],
"ConsecutiveBlockMinimization": [Consecutive Block Minimization],
"DirectedTwoCommodityIntegralFlow": [Directed Two-Commodity Integral Flow],
)

Expand Down Expand Up @@ -1649,6 +1650,40 @@ NP-completeness was established by Garey, Johnson, and Stockmeyer @gareyJohnsonS
]
}

#{
let x = load-model-example("ConsecutiveBlockMinimization")
let mat = x.instance.matrix
let K = x.instance.bound_k
let n-rows = mat.len()
let n-cols = if n-rows > 0 { mat.at(0).len() } else { 0 }
let sol = x.optimal.at(0)
let perm = sol.config
// Count blocks under the satisfying permutation
let total-blocks = 0
for row in mat {
let in-block = false
for p in perm {
if row.at(p) {
if not in-block {
total-blocks += 1
in-block = true
}
} else {
in-block = false
}
}
}
[
#problem-def("ConsecutiveBlockMinimization")[
Given an $m times n$ binary matrix $A$ and a positive integer $K$, determine whether there exists a permutation of the columns of $A$ such that the resulting matrix has at most $K$ maximal blocks of consecutive 1-entries (summed over all rows). A _block_ is a maximal contiguous run of 1-entries within a single row.
][
Consecutive Block Minimization (SR17 in Garey & Johnson) arises in consecutive file organization for information retrieval systems, where records stored on a linear medium must be arranged so that each query's relevant records form a contiguous segment. Applications also include scheduling, production planning, the glass cutting industry, and data compression. NP-complete by reduction from Hamiltonian Path @kou1977. When $K$ equals the number of non-all-zero rows, the problem reduces to testing the _consecutive ones property_, solvable in polynomial time via PQ-trees @booth1975. A 1.5-approximation is known @haddadi2008. The best known exact algorithm runs in $O^*(n!)$ by brute-force enumeration of all column permutations.

*Example.* Let $A$ be the #n-rows$times$#n-cols matrix with rows #mat.enumerate().map(((i, row)) => [$r_#i = (#row.map(v => if v {$1$} else {$0$}).join($,$))$]).join(", ") and $K = #K$. The column permutation $pi = (#perm.map(p => str(p)).join(", "))$ yields #total-blocks total blocks, so #total-blocks $<= #K$ and the answer is YES.
]
]
}

#{
let x = load-model-example("PaintShop")
let n-cars = x.instance.num_cars
Expand Down
29 changes: 29 additions & 0 deletions docs/paper/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -703,3 +703,32 @@ @article{papadimitriou1982
year = {1982},
doi = {10.1145/322307.322309}
}

@article{kou1977,
author = {Lawrence T. Kou},
title = {Polynomial Complete Consecutive Information Retrieval Problems},
journal = {SIAM Journal on Computing},
volume = {6},
number = {1},
pages = {67--75},
year = {1977},
doi = {10.1137/0206005}
}

@phdthesis{booth1975,
author = {Kellogg S. Booth},
title = {PQ Tree Algorithms},
school = {University of California, Berkeley},
year = {1975}
}

@article{haddadi2008,
author = {Salim Haddadi and Zohra Layouni},
title = {Consecutive block minimization is 1.5-approximable},
journal = {Information Processing Letters},
volume = {108},
number = {3},
pages = {161--163},
year = {2008},
doi = {10.1016/j.ipl.2008.05.003}
}
11 changes: 11 additions & 0 deletions docs/src/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ pred create SteinerTree --graph 0-1,0-3,1-2,1-3,2-3,2-4,3-4 --edge-weights 2,5,2
# Create a Length-Bounded Disjoint Paths instance
pred create LengthBoundedDisjointPaths --graph 0-1,1-6,0-2,2-3,3-6,0-4,4-5,5-6 --source 0 --sink 6 --num-paths-required 2 --bound 3 -o lbdp.json

# Create a Consecutive Block Minimization instance (alias: CBM)
pred create CBM --matrix '[[true,false,true],[false,true,true]]' --bound-k 2 -o cbm.json

# CBM currently needs the brute-force solver
pred solve cbm.json --solver brute-force

# Or start from a canonical model example
pred create --example MIS/SimpleGraph/i32 -o example.json

Expand Down Expand Up @@ -288,6 +294,7 @@ pred create MIS --graph 0-1,1-2,2-3 -o problem.json
pred create MIS --graph 0-1,1-2,2-3 --weights 2,1,3,1 -o problem.json
pred create SAT --num-vars 3 --clauses "1,2;-1,3" -o sat.json
pred create QUBO --matrix "1,0.5;0.5,2" -o qubo.json
pred create CBM --matrix '[[true,false,true],[false,true,true]]' --bound-k 2 -o cbm.json
pred create KColoring --k 3 --graph 0-1,1-2,2-0 -o kcol.json
pred create SpinGlass --graph 0-1,1-2 -o sg.json
pred create MaxCut --graph 0-1,1-2,2-0 -o maxcut.json
Expand All @@ -303,6 +310,10 @@ pred create MinimumTardinessSequencing --n 5 --deadlines 5,5,5,3,3 --precedence-
For `LengthBoundedDisjointPaths`, the CLI flag `--bound` maps to the JSON field
`max_length`.

For `ConsecutiveBlockMinimization`, the `--matrix` flag expects a JSON 2D bool array such as
`'[[true,false,true],[false,true,true]]'`. The example above shows the accepted shape, and solving
CBM instances currently requires `--solver brute-force`.

Canonical examples are useful when you want a known-good instance from the paper/example database.
For model examples, `pred create --example <PROBLEM_SPEC>` emits the canonical instance for that
graph node.
Expand Down
16 changes: 16 additions & 0 deletions docs/src/reductions/problem_schemas.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,22 @@
}
]
},
{
"name": "ConsecutiveBlockMinimization",
"description": "Permute columns of a binary matrix to have at most K consecutive blocks of 1s",
"fields": [
{
"name": "matrix",
"type_name": "Vec<Vec<bool>>",
"description": "Binary matrix A (m x n)"
},
{
"name": "bound_k",
"type_name": "usize",
"description": "Upper bound K on total consecutive blocks"
}
]
},
{
"name": "DirectedTwoCommodityIntegralFlow",
"description": "Two-commodity integral flow feasibility on a directed graph",
Expand Down
Loading