use crate::graph::*;
#[test]
fn test_apsp_linear_chain() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3)], false);
let dist = g.all_pairs_shortest_paths();
for (i, row) in dist.iter().enumerate().take(4) {
assert_eq!(row[i], Some(0));
}
assert_eq!(dist[0][1], Some(1));
assert_eq!(dist[0][2], Some(2));
assert_eq!(dist[0][3], Some(3));
assert_eq!(dist[1][2], Some(1));
assert_eq!(dist[1][3], Some(2));
assert_eq!(dist[2][3], Some(1));
assert_eq!(dist[0][3], dist[3][0]);
assert_eq!(dist[1][2], dist[2][1]);
}
#[test]
fn test_apsp_complete_graph() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)], false);
let dist = g.all_pairs_shortest_paths();
for (i, row) in dist.iter().enumerate().take(4) {
for (j, &cell) in row.iter().enumerate().take(4) {
if i == j {
assert_eq!(cell, Some(0));
} else {
assert_eq!(cell, Some(1));
}
}
}
}
#[test]
fn test_apsp_disconnected() {
let g = Graph::from_edges(&[(0, 1), (2, 3)], false);
let dist = g.all_pairs_shortest_paths();
assert_eq!(dist[0][1], Some(1));
assert_eq!(dist[1][0], Some(1));
assert_eq!(dist[2][3], Some(1));
assert_eq!(dist[3][2], Some(1));
assert_eq!(dist[0][2], None);
assert_eq!(dist[0][3], None);
assert_eq!(dist[1][2], None);
assert_eq!(dist[1][3], None);
}
#[test]
fn test_apsp_directed() {
let g = Graph::from_edges(&[(0, 1), (1, 2)], true);
let dist = g.all_pairs_shortest_paths();
assert_eq!(dist[0][1], Some(1));
assert_eq!(dist[0][2], Some(2));
assert_eq!(dist[1][2], Some(1));
assert_eq!(dist[1][0], None);
assert_eq!(dist[2][0], None);
assert_eq!(dist[2][1], None);
}
#[test]
fn test_apsp_triangle() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 0)], false);
let dist = g.all_pairs_shortest_paths();
for (i, row) in dist.iter().enumerate().take(3) {
for (j, &cell) in row.iter().enumerate().take(3) {
if i == j {
assert_eq!(cell, Some(0));
} else {
assert_eq!(cell, Some(1));
}
}
}
}
#[test]
fn test_apsp_star_graph() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3)], false);
let dist = g.all_pairs_shortest_paths();
assert_eq!(dist[0][1], Some(1));
assert_eq!(dist[0][2], Some(1));
assert_eq!(dist[0][3], Some(1));
assert_eq!(dist[1][2], Some(2));
assert_eq!(dist[1][3], Some(2));
assert_eq!(dist[2][3], Some(2));
}
#[test]
fn test_apsp_empty_graph() {
let g = Graph::new(false);
let dist = g.all_pairs_shortest_paths();
assert_eq!(dist.len(), 0);
}
#[test]
fn test_apsp_single_node() {
let g = Graph::from_edges(&[(0, 0)], false);
let dist = g.all_pairs_shortest_paths();
assert_eq!(dist.len(), 1);
assert_eq!(dist[0][0], Some(0));
}
#[test]
fn test_apsp_cycle() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3), (3, 0)], true);
let dist = g.all_pairs_shortest_paths();
assert_eq!(dist[0][1], Some(1));
assert_eq!(dist[0][2], Some(2));
assert_eq!(dist[0][3], Some(3));
assert_eq!(dist[1][3], Some(2));
for row in dist.iter().take(4) {
for &cell in row.iter().take(4) {
assert!(cell.is_some());
}
}
}
#[test]
fn test_apsp_matrix_size() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3)], false);
let dist = g.all_pairs_shortest_paths();
assert_eq!(dist.len(), 4);
for row in &dist {
assert_eq!(row.len(), 4);
}
}
#[test]
fn test_astar_linear_chain() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3)], false);
let heuristic = |node: usize| (3 - node) as f64;
let path = g.a_star(0, 3, heuristic).expect("path should exist");
assert_eq!(path, vec![0, 1, 2, 3]);
}
#[test]
fn test_astar_same_node() {
let g = Graph::from_edges(&[(0, 1)], false);
let heuristic = |_: usize| 0.0;
let path = g.a_star(0, 0, heuristic).expect("path should exist");
assert_eq!(path, vec![0]);
}
#[test]
fn test_astar_disconnected() {
let g = Graph::from_edges(&[(0, 1), (2, 3)], false);
let heuristic = |_: usize| 0.0;
assert!(g.a_star(0, 3, heuristic).is_none());
}
#[test]
fn test_astar_zero_heuristic() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3)], false);
let heuristic = |_: usize| 0.0;
let path = g.a_star(0, 3, heuristic).expect("path should exist");
assert_eq!(path, vec![0, 1, 2, 3]);
}
#[test]
fn test_astar_admissible_heuristic() {
let g =
Graph::from_weighted_edges(&[(0, 1, 1.0), (1, 2, 1.0), (0, 3, 0.5), (3, 2, 0.5)], false);
let heuristic = |node: usize| match node {
0 | 1 => 1.0, 3 => 0.5,
_ => 0.0, };
let path = g.a_star(0, 2, heuristic).expect("path should exist");
assert!(path.contains(&3)); }
#[test]
fn test_astar_directed() {
let g = Graph::from_edges(&[(0, 1), (1, 2)], true);
let heuristic = |node: usize| (2 - node) as f64;
let path = g
.a_star(0, 2, heuristic)
.expect("forward path should exist");
assert_eq!(path, vec![0, 1, 2]);
assert!(g.a_star(2, 0, |_| 0.0).is_none());
}
#[test]
fn test_astar_triangle() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 0)], false);
let heuristic = |_: usize| 0.0;
let path = g.a_star(0, 2, heuristic).expect("path should exist");
assert_eq!(path.len(), 2); assert_eq!(path[0], 0);
assert_eq!(path[1], 2);
}
#[test]
fn test_astar_weighted_graph() {
let g = Graph::from_weighted_edges(&[(0, 1, 1.0), (1, 2, 2.0), (0, 2, 5.0)], false);
let heuristic = |node: usize| match node {
0 => 3.0,
1 => 2.0,
_ => 0.0, };
let path = g.a_star(0, 2, heuristic).expect("path should exist");
assert_eq!(path, vec![0, 1, 2]);
}
#[test]
fn test_astar_complete_graph() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)], false);
let heuristic = |_: usize| 0.0;
let path = g.a_star(0, 3, heuristic).expect("path should exist");
assert_eq!(path.len(), 2); assert_eq!(path[0], 0);
assert_eq!(path[1], 3);
}
#[test]
fn test_astar_invalid_nodes() {
let g = Graph::from_edges(&[(0, 1)], false);
let heuristic = |_: usize| 0.0;
assert!(g.a_star(0, 10, heuristic).is_none());
assert!(g.a_star(10, 0, heuristic).is_none());
}
#[test]
fn test_astar_vs_shortest_path() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3)], false);
let sp_path = g
.shortest_path(0, 3)
.expect("shortest_path should find path");
let astar_path = g.a_star(0, 3, |_| 0.0).expect("astar should find path");
assert_eq!(sp_path.len(), astar_path.len());
assert_eq!(sp_path, astar_path);
}
#[test]
fn test_astar_star_graph() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3)], false);
let heuristic = |node: usize| if node == 3 { 0.0 } else { 1.0 };
let path = g.a_star(1, 3, heuristic).expect("path should exist");
assert_eq!(path.len(), 3); assert_eq!(path[0], 1);
assert_eq!(path[1], 0);
assert_eq!(path[2], 3);
}
#[test]
fn test_astar_perfect_heuristic() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3)], false);
let heuristic = |node: usize| (3 - node) as f64;
let path = g.a_star(0, 3, heuristic).expect("path should exist");
assert_eq!(path, vec![0, 1, 2, 3]);
}
#[test]
fn test_astar_complex_graph() {
let g = Graph::from_weighted_edges(
&[
(0, 1, 1.0),
(0, 2, 1.0),
(1, 3, 1.0),
(2, 3, 1.0),
(3, 4, 1.0),
],
false,
);
let heuristic = |node: usize| (4 - node) as f64;
let path = g.a_star(0, 4, heuristic).expect("path should exist");
assert_eq!(path.len(), 4); assert_eq!(path[0], 0);
assert_eq!(path[3], 4);
}
#[test]
fn test_dfs_linear_chain() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3)], false);
let visited = g.dfs(0).expect("valid source");
assert_eq!(visited.len(), 4);
assert_eq!(visited[0], 0); assert!(visited.contains(&1));
assert!(visited.contains(&2));
assert!(visited.contains(&3));
}
#[test]
fn test_dfs_tree() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3)], false);
let visited = g.dfs(0).expect("valid source");
assert_eq!(visited.len(), 4);
assert_eq!(visited[0], 0); assert!(visited.contains(&1));
assert!(visited.contains(&2));
assert!(visited.contains(&3));
}
#[test]
fn test_dfs_cycle() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 0)], false);
let visited = g.dfs(0).expect("valid source");
assert_eq!(visited.len(), 3);
assert_eq!(visited[0], 0);
assert!(visited.contains(&1));
assert!(visited.contains(&2));
}
#[test]
fn test_dfs_disconnected() {
let g = Graph::from_edges(&[(0, 1), (2, 3)], false);
let visited = g.dfs(0).expect("valid source");
assert_eq!(visited.len(), 2);
assert!(visited.contains(&0));
assert!(visited.contains(&1));
assert!(!visited.contains(&2));
assert!(!visited.contains(&3));
let visited2 = g.dfs(2).expect("valid source");
assert_eq!(visited2.len(), 2);
assert!(visited2.contains(&2));
assert!(visited2.contains(&3));
}
#[test]
fn test_dfs_directed() {
let g = Graph::from_edges(&[(0, 1), (1, 2)], true);
let visited = g.dfs(0).expect("valid source");
assert_eq!(visited.len(), 3);
assert_eq!(visited[0], 0);
let visited2 = g.dfs(2).expect("valid source");
assert_eq!(visited2.len(), 1);
assert_eq!(visited2[0], 2);
}
include!("advanced_dfs.rs");
include!("advanced_topological.rs");