2025-08-03: checkpoint

This commit is contained in:
2025-08-03 18:34:13 +02:00
parent 8d28ef44be
commit ba3cd9591e
16 changed files with 1219 additions and 354 deletions

87
src/testing.rs Normal file
View File

@@ -0,0 +1,87 @@
use itertools::Itertools;
use crate::{algorithms::{Dinic, EdmondsKarp, FordFulkerson, GoldbergTarjan, MaxflowAlgorithm, MaxflowAlgorithmEnum}, random_generator::MaxflowProblem, graph::FlowGraph};
use std::time::{Instant};
fn solve_problem_all_algos(problem: &MaxflowProblem) -> (f64, f64, f64, f64) {
let ff = FordFulkerson::from_problem(&problem);
let ek = EdmondsKarp::from_problem(&problem);
let di = Dinic::from_problem(&problem);
let gt = GoldbergTarjan::from_problem(&problem);
let mut instances:Vec<MaxflowAlgorithmEnum> = vec![ff.into(), ek.into(), di.into(), gt.into()];
let mut durations = vec![0.0; 4];
for (i,a) in instances.iter_mut().enumerate() {
let now = Instant::now();
match a {
MaxflowAlgorithmEnum::GoldbergTarjan(_) => { a.run(); },
_ => {
a.run();
}
}
//a.run();
durations[i] = now.elapsed().as_secs_f64();
// check if the flow is valid
assert!(a.graph().valid_flow(problem.s, problem.t), "invalid flow");
}
// check if all algorithms return the same total flow
let total_flows: Vec<u64> = instances.iter_mut().map(|x| x.graph().total_flow(problem.s, problem.t)).collect();
println!("total flows: {:?}", total_flows);
assert!(total_flows.iter().all(|&x| x == total_flows[0]), "algorithms return different total flows");
return durations.into_iter().collect_tuple().unwrap();
}
fn run_tests(test_tuples: Vec<(u64, u64, u64)>) -> String {
let mut response = String::new();
for (problem_count, nodes, capacity) in test_tuples {
response += format!("=== Testing with problem_count={}, nodes={}, capacity={}\n", problem_count, nodes, capacity).as_str();
let mut problems: Vec<_> = Vec::new();
for _ in 0..problem_count {
problems.push(MaxflowProblem::new_random_graph(nodes, capacity));
}
let mut durations = Vec::new();
for (_, problem) in problems.iter_mut().enumerate() {
durations.push(solve_problem_all_algos(problem));
}
let d0 = durations.iter().map(|x| x.0).sum::<f64>() / problem_count as f64;
let d1 = durations.iter().map(|x| x.1).sum::<f64>() / problem_count as f64;
let d2 = durations.iter().map(|x| x.2).sum::<f64>() / problem_count as f64;
let d3 = durations.iter().map(|x| x.3).sum::<f64>() / problem_count as f64;
response += format!("Ford-Fulkerson:\t{:02.8}s\nEdmonds-Karp:\t{:02.8}s\nDinic:\t\t\t\t\t\t{:02.8}s\nGoldberg-Tarjan:\t{:02.8}s\n\n", d0, d1, d2, d3).as_str();
}
return response
}
pub fn run_small_tests() -> String {
let test_tuples = [
// (number of problems, number of nodes, max. capacity)
(10, 10, 10),
(10, 100, 10),
(10, 100, 100),
(10, 200, 10),
(10, 200, 100)
];
return run_tests(test_tuples.into());
}
pub fn run_large_tests() -> String {
let test_tuples = [
// (number of problems, number of nodes, max. capacity)
(10, 100, 10),
(10, 100, 100),
(10, 100, 1000),
(10, 500, 10),
(10, 500, 100),
(10, 500, 1000),
(10, 1000, 10),
(10, 1000, 100),
(10, 1000, 1000),
(10, 10000, 10)
];
return run_tests(test_tuples.into());
}