brute_force.rs |
Brute-force algorithm for finding column minima.
The functions here are mostly meant to be used for testing
correctness of the SMAWK implementation.
**Note: this module is only available if you enable the `ndarray`
Cargo feature.** |
4232 |
lib.rs |
This crate implements various functions that help speed up dynamic
programming, most importantly the SMAWK algorithm for finding row
or column minima in a totally monotone matrix with *m* rows and
*n* columns in time O(*m* + *n*). This is much better than the
brute force solution which would take O(*mn*). When *m* and *n*
are of the same order, this turns a quadratic function into a
linear function.
# Examples
Computing the column minima of an *m* ✕ *n* Monge matrix can be
done efficiently with `smawk::column_minima`:
```
use smawk::Matrix;
let matrix = vec![
vec![3, 2, 4, 5, 6],
vec![2, 1, 3, 3, 4],
vec![2, 1, 3, 3, 4],
vec![3, 2, 4, 3, 4],
vec![4, 3, 2, 1, 1],
];
let minima = vec![1, 1, 4, 4, 4];
assert_eq!(smawk::column_minima(&matrix), minima);
```
The `minima` vector gives the index of the minimum value per
column, so `minima[0] == 1` since the minimum value in the first
column is 2 (row 1). Note that the smallest row index is returned.
# Definitions
Some of the functions in this crate only work on matrices that are
*totally monotone*, which we will define below.
## Monotone Matrices
We start with a helper definition. Given an *m* ✕ *n* matrix `M`,
we say that `M` is *monotone* when the minimum value of row `i` is
found to the left of the minimum value in row `i'` where `i < i'`.
More formally, if we let `rm(i)` denote the column index of the
left-most minimum value in row `i`, then we have
```text
rm(0) ≤ rm(1) ≤ ... ≤ rm(m - 1)
```
This means that as you go down the rows from top to bottom, the
row-minima proceed from left to right.
The algorithms in this crate deal with finding such row- and
column-minima.
## Totally Monotone Matrices
We say that a matrix `M` is *totally monotone* when every
sub-matrix is monotone. A sub-matrix is formed by the intersection
of any two rows `i < i'` and any two columns `j < j'`.
This is often expressed as via this equivalent condition:
```text
M[i, j] > M[i, j'] => M[i', j] > M[i', j']
```
for all `i < i'` and `j < j'`.
## Monge Property for Matrices
A matrix `M` is said to fulfill the *Monge property* if
```text
M[i, j] + M[i', j'] ≤ M[i, j'] + M[i', j]
```
for all `i < i'` and `j < j'`. This says that given any rectangle
in the matrix, the sum of the top-left and bottom-right corners is
less than or equal to the sum of the bottom-left and upper-right
corners.
All Monge matrices are totally monotone, so it is enough to
establish that the Monge property holds in order to use a matrix
with the functions in this crate. If your program is dealing with
unknown inputs, it can use [`monge::is_monge`] to verify that a
matrix is a Monge matrix. |
17893 |
monge.rs |
Functions for generating and checking Monge arrays.
The functions here are mostly meant to be used for testing
correctness of the SMAWK implementation. |
3587 |
recursive.rs |
Recursive algorithm for finding column minima.
The functions here are mostly meant to be used for testing
correctness of the SMAWK implementation.
**Note: this module is only available if you enable the `ndarray`
Cargo feature.** |
5524 |