Arithmetic Nonmax
The arithmetic-nonmax crate provides NonMax* types for integer types that are guaranteed to never be their maximum value (MAX). Using NonMax* types enables memory layout optimization.
Additionally, arithmetic operations can be written intuitively as shown below. For example, in shortest path algorithms, using the Option<NonMax*> type allows you to leverage the type system while optimizing the memory layout. See Benchmarks for more details.
use ;
let a: NonMaxU32 = new.unwrap;
let b = non_max!; // Conveniently create values with the non_max! macro
let c = b - a; // Arithmetic operations between NonMax types
assert_eq!;
let d = a * 5; // Arithmetic operations with primitive integers
assert!;
assert_eq!; // Can be converted to string
Memory layout optimization can be verified as follows:
use *;
// Check byte size for u32
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
// Check byte size for Option<NonMax*>
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Benchmarks
Benchmarks are available in benches/comparison.rs. They compare execution time and memory usage between using and not using NonMax types.
| Algorithm | With NonMax |
Without NonMax |
With Sentinel |
|---|---|---|---|
| Dijkstra ($V=5.0 \times 105, E = 5.0 \times 106$) | 447ms / 18.8MB | 487ms / 20.8MB | 456ms / 18.8MB |
| Floyd-Warshall ($V=5.0 \times 102, E = 5.0 \times 103$) | 100ms / 1.00MB | 126ms / 2.00MB | 83ms / 1.00MB |
In the Dijkstra algorithm, the NonMax implementation is faster than using manual sentinel values. This is due to specialized optimizations leveraged by the internal representation where None is mapped to 0.
Examples
You can find programs that solve Aizu Online Judge problems using this library in the examples/ directory.
Note that you need to bundle the library into a single file when submitting to an online judge.
- GRL_1_A: Single Source Shortest Path: Uses
Option<NonMax<u32>>for distances, representing unreachable nodes asNone. - GRL_1_C: All Pairs Shortest Path: Uses
Option<NonMax<i32>>for distances, representing unreachable nodes asNone. - DSL_1_A: Disjoint Set: Manages parent indices in a Union-Find data structure using
Option<NonMaxUsize>.