use tide_maxflow::max_flow;
fn layered_graph(layers: usize, width: usize) -> (usize, usize, usize, Vec<(usize, usize, i64)>) {
let s = 0;
let t = layers * width + 1;
let n = t + 1;
let vid = |l: usize, p: usize| l * width + p + 1;
let mut edges = Vec::new();
for p in 0..width {
edges.push((s, vid(0, p), (50 + p) as i64));
}
for l in 0..layers - 1 {
for p in 0..width {
for d in 0..=2 {
edges.push((vid(l, p), vid(l + 1, (p + d) % width), (10 + p + d) as i64));
}
}
}
for p in 0..width {
edges.push((vid(layers - 1, p), t, (50 + p) as i64));
}
(n, s, t, edges)
}
fn grid_graph(rows: usize, cols: usize) -> (usize, usize, usize, Vec<(usize, usize, i64)>) {
let s = 0;
let t = rows * cols + 1;
let n = t + 1;
let vid = |r: usize, c: usize| r * cols + c + 1;
let mut edges = Vec::new();
for c in 0..cols {
edges.push((s, vid(0, c), (50 + c) as i64));
}
for r in 0..rows {
for c in 0..cols - 1 {
edges.push((vid(r, c), vid(r, c + 1), (5 + r + c) as i64));
}
}
for r in 0..rows - 1 {
for c in 0..cols {
edges.push((vid(r, c), vid(r + 1, c), (5 + r + c) as i64));
}
}
for c in 0..cols {
edges.push((vid(rows - 1, c), t, (50 + c) as i64));
}
(n, s, t, edges)
}
fn bipartite_graph(left: usize, right: usize) -> (usize, usize, usize, Vec<(usize, usize, i64)>) {
let s = 0;
let t = left + right + 1;
let n = t + 1;
let mut edges = Vec::new();
for i in 0..left {
edges.push((s, 1 + i, (100 + (i * 7) % 50) as i64));
}
for i in 0..left {
for j in 0..right {
edges.push((1 + i, 1 + left + j, (10 + (i * 13 + j * 7) % 40) as i64));
}
}
for j in 0..right {
edges.push((1 + left + j, t, (100 + (j * 11) % 50) as i64));
}
(n, s, t, edges)
}
fn random_graph(
n_inner: usize,
edge_prob_pct: usize,
max_cap: i64,
) -> (usize, usize, usize, Vec<(usize, usize, i64)>) {
let s = 0;
let t = n_inner + 1;
let n = t + 1;
let mut edges = Vec::new();
let mut lcg: u64 = 12345;
for v in 1..=n_inner {
lcg = lcg.wrapping_mul(6364136223846793005).wrapping_add(1);
let cap = (lcg % max_cap as u64) as i64 + 1;
edges.push((s, v, cap));
}
for u in 1..=n_inner {
for v in 1..=n_inner {
if u != v {
lcg = lcg.wrapping_mul(6364136223846793005).wrapping_add(1);
if (lcg % 100) < edge_prob_pct as u64 {
lcg = lcg.wrapping_mul(6364136223846793005).wrapping_add(1);
let cap = (lcg % max_cap as u64) as i64 + 1;
edges.push((u, v, cap));
}
}
}
}
for v in 1..=n_inner {
lcg = lcg.wrapping_mul(6364136223846793005).wrapping_add(1);
let cap = (lcg % max_cap as u64) as i64 + 1;
edges.push((v, t, cap));
}
(n, s, t, edges)
}
fn parallel_chains(k: usize, len: usize) -> (usize, usize, usize, Vec<(usize, usize, i64)>) {
let s = 0;
let t = k * len + 1;
let n = t + 1;
let mut edges = Vec::new();
for chain in 0..k {
let first = 1 + chain * len;
let last = first + len - 1;
edges.push((s, first, (50 + chain * 3) as i64));
for i in 0..len - 1 {
edges.push((first + i, first + i + 1, (20 + chain + i) as i64));
}
edges.push((last, t, (50 + chain * 3) as i64));
}
(n, s, t, edges)
}
fn main() {
println!("graph_id,name,n,m,max_flow,steps");
let graphs: Vec<(&str, (usize, usize, usize, Vec<(usize, usize, i64)>))> = vec![
("layered_5x5", layered_graph(5, 5)),
("layered_10x10", layered_graph(10, 10)),
("layered_20x10", layered_graph(20, 10)),
("layered_50x50", layered_graph(50, 50)),
("grid_5x5", grid_graph(5, 5)),
("grid_10x10", grid_graph(10, 10)),
("grid_20x20", grid_graph(20, 20)),
("grid_50x50", grid_graph(50, 50)),
("bipartite_5x5", bipartite_graph(5, 5)),
("bipartite_10x10", bipartite_graph(10, 10)),
("bipartite_20x20", bipartite_graph(20, 20)),
("bipartite_50x50", bipartite_graph(50, 50)),
("random_20_10pct", random_graph(20, 10, 100)),
("random_20_30pct", random_graph(20, 30, 100)),
("random_50_10pct", random_graph(50, 10, 100)),
("random_50_30pct", random_graph(50, 30, 100)),
("chains_5x10", parallel_chains(5, 10)),
("chains_10x20", parallel_chains(10, 20)),
("chains_20x10", parallel_chains(20, 10)),
(
"clrs",
(
6,
0,
5,
vec![
(0, 1, 16),
(0, 2, 13),
(1, 2, 10),
(1, 3, 12),
(2, 1, 4),
(2, 4, 14),
(3, 2, 9),
(3, 5, 20),
(4, 3, 7),
(4, 5, 4),
],
),
),
];
for (gid, (name, (n, s, t, edges))) in graphs.iter().enumerate() {
let result = max_flow(*n, *s, *t, edges);
println!(
"{},{},{},{},{},{}",
gid,
name,
n,
edges.len(),
result.flow,
result.steps
);
}
}