Change "neighbor" terminology to "adjacent vertex" throughout the code

This commit is contained in:
2026-05-07 17:34:20 +02:00
parent 726e7691ea
commit a7be995e34
5 changed files with 61 additions and 61 deletions
+7 -7
View File
@@ -33,8 +33,8 @@ where
W: Fn(G::Edge) -> u32, W: Fn(G::Edge) -> u32,
{ {
let mut predecessors = graph.vertex_map(None); let mut predecessors = graph.vertex_map(None);
let distances = dijkstra_impl(graph, source, weight, |neighbor, predecessor| { let distances = dijkstra_impl(graph, source, weight, |adjacent, predecessor| {
predecessors[neighbor] = Some(predecessor); predecessors[adjacent] = Some(predecessor);
}); });
DijkstraResult { DijkstraResult {
distances, distances,
@@ -92,19 +92,19 @@ where
}); });
while let Some(v) = heap.pop() { while let Some(v) = heap.pop() {
for neighbor in graph.neighbors(v.vertex) { for adjacent in graph.adjacent_vertices(v.vertex) {
// TODO: Use custom edge weights in Dijkstra's algorithm. // TODO: Use custom edge weights in Dijkstra's algorithm.
let edge_weight = 1; let edge_weight = 1;
let new_distance = distances[v.vertex].unwrap() + edge_weight; let new_distance = distances[v.vertex].unwrap() + edge_weight;
if match distances[neighbor] { if match distances[adjacent] {
None => true, None => true,
Some(old_distance) if old_distance > new_distance => true, Some(old_distance) if old_distance > new_distance => true,
_ => false, _ => false,
} { } {
distances[neighbor] = Some(new_distance); distances[adjacent] = Some(new_distance);
on_relax(neighbor, v.vertex); on_relax(adjacent, v.vertex);
heap.push(DistanceOrderedVertex { heap.push(DistanceOrderedVertex {
vertex: neighbor, vertex: adjacent,
distance: new_distance, distance: new_distance,
}); });
} }
+8 -8
View File
@@ -20,22 +20,22 @@ struct VertexIncidenceHeader {
struct IncidenceEntry { struct IncidenceEntry {
next: Option<Incidence>, next: Option<Incidence>,
neighbor: Vertex, adjacent: Vertex,
} }
struct VertexNeighborIterator<'a> { struct VertexAdjacenceIterator<'a> {
graph: &'a AppendGraph, graph: &'a AppendGraph,
incidence: Option<Incidence>, incidence: Option<Incidence>,
} }
impl<'a> Iterator for VertexNeighborIterator<'a> { impl<'a> Iterator for VertexAdjacenceIterator<'a> {
type Item = Vertex; type Item = Vertex;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let incidence = self.incidence?; let incidence = self.incidence?;
let entry = &self.graph.incidences[incidence.0]; let entry = &self.graph.incidences[incidence.0];
self.incidence = entry.next; self.incidence = entry.next;
Some(entry.neighbor) Some(entry.adjacent)
} }
} }
@@ -58,7 +58,7 @@ impl AppendGraph {
fn add_incidence(&mut self, v1: Vertex, v2: Vertex) { fn add_incidence(&mut self, v1: Vertex, v2: Vertex) {
self.incidences.push(IncidenceEntry { self.incidences.push(IncidenceEntry {
next: self.vertices[v1.0].first_incidence.take(), next: self.vertices[v1.0].first_incidence.take(),
neighbor: v2, adjacent: v2,
}); });
self.vertices[v1.0].incidence_count += 1; self.vertices[v1.0].incidence_count += 1;
self.vertices[v1.0].first_incidence = Some(Incidence(self.incidences.len() - 1)); self.vertices[v1.0].first_incidence = Some(Incidence(self.incidences.len() - 1));
@@ -105,15 +105,15 @@ impl GraphTopology for AppendGraph {
} }
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool { fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool {
self.neighbors(v1).any(|x| x == v2) self.adjacent_vertices(v1).any(|x| x == v2)
} }
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> { fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
(0..self.vertices.len()).map(Vertex) (0..self.vertices.len()).map(Vertex)
} }
fn neighbors(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex> { fn adjacent_vertices(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex> {
VertexNeighborIterator { VertexAdjacenceIterator {
graph: self, graph: self,
incidence: self.vertices[v.0].first_incidence, incidence: self.vertices[v.0].first_incidence,
} }
+17 -17
View File
@@ -20,15 +20,15 @@ pub struct VertexIncidenceHeader {
pub struct IncidenceEntry { pub struct IncidenceEntry {
next: Option<IncidenceSlot>, next: Option<IncidenceSlot>,
neighbor: VertexSlot, adjacent: VertexSlot,
} }
struct VertexNeighborIterator<'a> { struct VertexAdjacenceIterator<'a> {
graph: &'a Graph, graph: &'a Graph,
incidence: Option<IncidenceSlot>, incidence: Option<IncidenceSlot>,
} }
impl<'a> Iterator for VertexNeighborIterator<'a> { impl<'a> Iterator for VertexAdjacenceIterator<'a> {
type Item = Vertex; type Item = Vertex;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@@ -37,7 +37,7 @@ impl<'a> Iterator for VertexNeighborIterator<'a> {
let index = self.graph.incidences.get_idx(incidence.0)?; let index = self.graph.incidences.get_idx(incidence.0)?;
let entry = &self.graph.incidences[index]; let entry = &self.graph.incidences[index];
self.incidence = entry.next; self.incidence = entry.next;
self.graph.vertices.get_idx(entry.neighbor.0) self.graph.vertices.get_idx(entry.adjacent.0)
} }
} }
@@ -89,7 +89,7 @@ impl Graph {
fn add_incidence(&mut self, v1: Vertex, v2: Vertex) -> Edge { fn add_incidence(&mut self, v1: Vertex, v2: Vertex) -> Edge {
let edge = self.incidences.insert(IncidenceEntry { let edge = self.incidences.insert(IncidenceEntry {
next: self.vertices[v1].first_incidence.take(), next: self.vertices[v1].first_incidence.take(),
neighbor: VertexSlot(v2.arr_idx()), adjacent: VertexSlot(v2.arr_idx()),
}); });
self.vertices[v1].incidence_count += 1; self.vertices[v1].incidence_count += 1;
self.vertices[v1].first_incidence = Some(IncidenceSlot(edge.arr_idx())); self.vertices[v1].first_incidence = Some(IncidenceSlot(edge.arr_idx()));
@@ -124,12 +124,12 @@ impl Graph {
let source_vertex = self let source_vertex = self
.vertices .vertices
.get_idx(source.0) .get_idx(source.0)
.expect("missing incident neighbor, corrupt internal data state"); .expect("missing incident vertex, corrupt internal data state");
let vertex_header = &mut self.vertices[source_vertex]; let vertex_header = &mut self.vertices[source_vertex];
vertex_header.incidence_count -= if is_loop { 2 } else { 1 }; vertex_header.incidence_count -= if is_loop { 2 } else { 1 };
let first = vertex_header let first = vertex_header
.first_incidence .first_incidence
.expect("incident neighbor without incidences, corrupt internal data state"); .expect("incident vertex without incidences, corrupt internal data state");
if first.0 == e.arr_idx() { if first.0 == e.arr_idx() {
vertex_header.first_incidence = next; vertex_header.first_incidence = next;
} else { } else {
@@ -184,15 +184,15 @@ impl GraphTopology for Graph {
} }
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool { fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool {
self.neighbors(v1).any(|x| x == v2) self.adjacent_vertices(v1).any(|x| x == v2)
} }
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> { fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
self.vertices.iter().map(|(i, _)| i) self.vertices.iter().map(|(i, _)| i)
} }
fn neighbors(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex> { fn adjacent_vertices(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex> {
VertexNeighborIterator { VertexAdjacenceIterator {
graph: self, graph: self,
incidence: self.vertices[v].first_incidence, incidence: self.vertices[v].first_incidence,
} }
@@ -233,8 +233,8 @@ impl GraphTopologyDeletion for Graph {
// Since v is being deleted, there are no update_incidence_list() calls for e, no need // Since v is being deleted, there are no update_incidence_list() calls for e, no need
// to fix v's incidence list. // to fix v's incidence list.
let (f, e_entry, f_entry) = self.remove_incidence_pair(e); let (f, e_entry, f_entry) = self.remove_incidence_pair(e);
if e_entry.neighbor != f_entry.neighbor { if e_entry.adjacent != f_entry.adjacent {
self.update_incidence_list(f, e_entry.neighbor, f_entry.next, false); self.update_incidence_list(f, e_entry.adjacent, f_entry.next, false);
} else { } else {
cursor.incidence = f_entry.next; cursor.incidence = f_entry.next;
} }
@@ -246,13 +246,13 @@ impl GraphTopologyDeletion for Graph {
// the predecessor, never the removed entries themselves. // the predecessor, never the removed entries themselves.
fn delete_edge(&mut self, e: Self::Edge) { fn delete_edge(&mut self, e: Self::Edge) {
let (f, e_entry, f_entry) = self.remove_incidence_pair(e); let (f, e_entry, f_entry) = self.remove_incidence_pair(e);
if e_entry.neighbor != f_entry.neighbor { if e_entry.adjacent != f_entry.adjacent {
self.update_incidence_list(e, f_entry.neighbor, e_entry.next, false); self.update_incidence_list(e, f_entry.adjacent, e_entry.next, false);
self.update_incidence_list(f, e_entry.neighbor, f_entry.next, false); self.update_incidence_list(f, e_entry.adjacent, f_entry.next, false);
} else if f_entry.next.is_some_and(|i| e.arr_idx() == i.0) { } else if f_entry.next.is_some_and(|i| e.arr_idx() == i.0) {
self.update_incidence_list(f, e_entry.neighbor, e_entry.next, true); self.update_incidence_list(f, e_entry.adjacent, e_entry.next, true);
} else { } else {
self.update_incidence_list(e, e_entry.neighbor, f_entry.next, true); self.update_incidence_list(e, e_entry.adjacent, f_entry.next, true);
} }
} }
} }
+28 -28
View File
@@ -192,26 +192,26 @@ macro_rules! graph_topology_tests {
} }
#[test] #[test]
fn neighbors_empty() { fn adjacent_vertices_empty() {
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let vertex = graph.add_vertex(); let vertex = graph.add_vertex();
assert_eq!( assert_eq!(
graph.neighbors(vertex).count(), graph.adjacent_vertices(vertex).count(),
0, 0,
"neighbor iterator of vertex with degree 0 should have no elements" "adjacent vertex iterator of vertex with degree 0 should have no elements"
); );
} }
#[test] #[test]
fn neighbors() { fn adjacent_vertices() {
let (graph, vertices, _) = make_test_graph(); let (graph, vertices, _) = make_test_graph();
// Checks neighbors of vertex 4. // Checks adjacency of vertex 4.
assert_eq!( assert_eq!(
graph.neighbors(vertices[4]).count(), graph.adjacent_vertices(vertices[4]).count(),
7, 7,
"unexpected neighbor count" "unexpected adjacency count"
); );
let mut expected_neighbors = vec![ let mut expected_adjacency = vec![
vertices[1], vertices[1],
vertices[2], vertices[2],
vertices[2], vertices[2],
@@ -220,21 +220,21 @@ macro_rules! graph_topology_tests {
vertices[7], vertices[7],
vertices[8], vertices[8],
]; ];
for v in graph.neighbors(vertices[4]) { for v in graph.adjacent_vertices(vertices[4]) {
let i = expected_neighbors let i = expected_adjacency
.iter() .iter()
.position(|w| *w == v) .position(|w| *w == v)
.expect(&format!( .expect(&format!(
"unexpected neighbor {v:?} of {:?} from the iterator", "unexpected adjacent vertex {v:?} of {:?} from the iterator",
vertices[4] vertices[4]
)); ));
expected_neighbors.swap_remove(i); expected_adjacency.swap_remove(i);
} }
assert_eq!( assert_eq!(
expected_neighbors.len(), expected_adjacency.len(),
0, 0,
"expected neighbors {:?} of {:?} were not matched by the iterator", "expected adjacent vertices {:?} of {:?} were not matched by the iterator",
expected_neighbors, expected_adjacency,
vertices[4] vertices[4]
); );
} }
@@ -276,18 +276,18 @@ macro_rules! graph_topology_tests {
graph.are_adjacent(v, v), graph.are_adjacent(v, v),
"vertex with loop edge should be adjacent to itself" "vertex with loop edge should be adjacent to itself"
); );
let mut neighbors = graph.neighbors(v); let mut iter = graph.adjacent_vertices(v);
assert_eq!(iter.next(), Some(v), "vertex should be adjacent to itself");
assert_eq!( assert_eq!(
neighbors.next(), iter.next(),
Some(v), Some(v),
"vertex should be neighbor of itself" "vertex should be adjacent to itself twice"
); );
assert_eq!( assert_eq!(
neighbors.next(), iter.next(),
Some(v), None,
"vertex should be neighbor of itself twice" "too many adjacent vertices from iterator"
); );
assert_eq!(neighbors.next(), None, "too many neighbors from iterator");
} }
#[test] #[test]
@@ -312,20 +312,20 @@ macro_rules! graph_topology_tests {
"should be adjacent" "should be adjacent"
); );
for i in 0..2 { for i in 0..2 {
let mut neighbors = graph.neighbors(vertices[i]); let mut iter = graph.adjacent_vertices(vertices[i]);
for j in 0..k { for j in 0..k {
assert_eq!( assert_eq!(
neighbors.next(), iter.next(),
Some(vertices[1 - i]), Some(vertices[1 - i]),
"neighbor {j} of vertex {:?} should be {:?}", "adjacent vertex {j} of vertex {:?} should be {:?}",
vertices[i], vertices[i],
vertices[1 - i] vertices[1 - i]
); );
} }
assert_eq!( assert_eq!(
neighbors.next(), iter.next(),
None, None,
"too many neighbors of {:?} from iterator", "too many adjacent vertices of {:?} from iterator",
vertices[i] vertices[i]
); );
} }
@@ -439,7 +439,7 @@ macro_rules! graph_topology_deletion_tests {
} }
for v in [vertices[1], vertices[4], vertices[5], vertices[6]] { for v in [vertices[1], vertices[4], vertices[5], vertices[6]] {
assert!( assert!(
!graph.neighbors(v).any(|u| u == vertices[2]), !graph.adjacent_vertices(v).any(|u| u == vertices[2]),
"unexpected adjacency of {v:?} to deleted vertex {:?}", "unexpected adjacency of {v:?} to deleted vertex {:?}",
vertices[2] vertices[2]
); );
+1 -1
View File
@@ -17,7 +17,7 @@ pub trait GraphTopology {
fn degree(&self, v: Self::Vertex) -> usize; fn degree(&self, v: Self::Vertex) -> usize;
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool; fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool;
fn vertices(&self) -> impl Iterator<Item = Self::Vertex>; fn vertices(&self) -> impl Iterator<Item = Self::Vertex>;
fn neighbors(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex>; fn adjacent_vertices(&self, v: Self::Vertex) -> impl Iterator<Item = Self::Vertex>;
fn edges(&self) -> impl Iterator<Item = Self::Edge>; fn edges(&self) -> impl Iterator<Item = Self::Edge>;
fn add_vertex(&mut self) -> Self::Vertex; fn add_vertex(&mut self) -> Self::Vertex;
fn add_edge(&mut self, v1: Self::Vertex, v2: Self::Vertex) -> Self::Edge; fn add_edge(&mut self, v1: Self::Vertex, v2: Self::Vertex) -> Self::Edge;