Common neighbors #9
+110
-19
@@ -84,37 +84,128 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::*;
|
||||
use crate::models::{FrozenGraph, Graph};
|
||||
|
||||
#[test]
|
||||
fn petersen() {
|
||||
let mut graph = AppendGraph::new();
|
||||
let (vertices, edges) = super::petersen(&mut graph);
|
||||
assert_eq!(
|
||||
graph.vertex_count(),
|
||||
10,
|
||||
"unexpected number of added vertices"
|
||||
);
|
||||
assert_eq!(graph.edge_count(), 15, "unexpected number of added edges");
|
||||
fn petersen_append_graph() {
|
||||
petersen_add::<AppendGraph>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn petersen_graph() {
|
||||
petersen_add::<Graph>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn petersen_frozen_graph() {
|
||||
petersen_generate_as::<FrozenGraph>();
|
||||
}
|
||||
|
||||
fn petersen_generate_as<G: GraphTopologyConversion>()
|
||||
where
|
||||
G::Vertex: Debug,
|
||||
G::Edge: Debug,
|
||||
{
|
||||
let (graph, vertices, edges) = generate_as::<G, _, _>(petersen);
|
||||
assert_petersen(&graph, &vertices, &edges);
|
||||
}
|
||||
|
||||
fn petersen_add<G: GraphTopologyAddition>()
|
||||
where
|
||||
G::Vertex: Debug,
|
||||
G::Edge: Debug,
|
||||
{
|
||||
let mut graph = G::default();
|
||||
let (vertices, edges) = petersen(&mut graph);
|
||||
assert_petersen(&graph, &vertices, &edges);
|
||||
}
|
||||
|
||||
fn assert_petersen<G: GraphTopology>(graph: &G, vertices: &[G::Vertex], edges: &[G::Edge])
|
||||
where
|
||||
G::Vertex: Debug,
|
||||
G::Edge: Debug,
|
||||
{
|
||||
assert_element_counts(graph, 10, 15);
|
||||
assert_handles(graph.vertices(), vertices, "vertex");
|
||||
assert_handles(graph.edges(), edges, "edge");
|
||||
assert_no_loops_no_multi_edges(graph);
|
||||
assert!(
|
||||
graph.vertices().all(|v| graph.degree(v) == 3),
|
||||
"all vertices should have degree 3"
|
||||
);
|
||||
assert_handles_in_graph(&graph, &vertices, &edges);
|
||||
// Checks that each pair of vertices (u, v) has no common neighbor if they are adjacent, and
|
||||
// exactly one common neighbor otherwise.
|
||||
for (i, &v) in vertices.iter().enumerate() {
|
||||
for &u in &vertices[i + 1..] {
|
||||
if graph.are_adjacent(v, u) {
|
||||
assert!(
|
||||
graph.common_neighbors(u, v).next().is_none(),
|
||||
"adjacent vertices {u:?} and {v:?} should not have a common neighbor"
|
||||
);
|
||||
} else {
|
||||
assert_eq!(
|
||||
graph.common_neighbors(u, v).count(),
|
||||
1,
|
||||
"non-adjacent vertices {u:?} and {v:?} should have exactly one common neighbor"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_handles_in_graph<G: GraphTopology>(
|
||||
fn assert_element_counts<G: GraphTopology>(
|
||||
graph: &G,
|
||||
vertices: &[G::Vertex],
|
||||
edges: &[G::Edge],
|
||||
expected_vertex_count: usize,
|
||||
expected_edge_count: usize,
|
||||
) {
|
||||
assert!(
|
||||
vertices.iter().all(|&v| graph.vertices().any(|u| u == v)),
|
||||
"all returned vertices should be in the graph"
|
||||
assert_eq!(
|
||||
graph.vertex_count(),
|
||||
expected_vertex_count,
|
||||
"unexpected number of vertices"
|
||||
);
|
||||
assert!(
|
||||
edges.iter().all(|&e| graph.edges().any(|f| f == e)),
|
||||
"all returned edges should be in the graph"
|
||||
assert_eq!(
|
||||
graph.edge_count(),
|
||||
expected_edge_count,
|
||||
"unexpected number of edges"
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts that every handle in `returned` is unique and in `all`.
|
||||
fn assert_handles<T: PartialEq + Debug>(
|
||||
all: impl Iterator<Item = T>,
|
||||
returned: &[T],
|
||||
kind: &str,
|
||||
) {
|
||||
let mut remaining: Vec<T> = all.collect();
|
||||
for e in returned {
|
||||
let Some(position) = remaining.iter().position(|x| x == e) else {
|
||||
panic!("returned {kind} {e:?} is not in the graph or appears more than once");
|
||||
};
|
||||
remaining.swap_remove(position);
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_no_loops_no_multi_edges<G: GraphTopology>(graph: &G)
|
||||
where
|
||||
G::Vertex: Debug,
|
||||
G::Edge: Debug,
|
||||
{
|
||||
for e in graph.edges() {
|
||||
let (u, v) = graph.incident_vertices(e);
|
||||
assert_ne!(u, v, "unexpected loop edge {e:?}");
|
||||
}
|
||||
for v in graph.vertices() {
|
||||
let mut neighbors = Vec::new();
|
||||
for u in graph.adjacent_vertices(v) {
|
||||
assert!(
|
||||
!neighbors.contains(&u),
|
||||
"unexpected multi-edge between {v:?} and {u:?}"
|
||||
);
|
||||
neighbors.push(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user