Add "algorithms" and "models" modules for existing code and related todos

This commit is contained in:
2025-10-08 14:32:52 +02:00
parent 46675a1246
commit 720f497b64
3 changed files with 156 additions and 145 deletions
+70
View File
@@ -0,0 +1,70 @@
use std::cmp::Ordering;
use std::collections::BinaryHeap;
use crate::models::Graph;
use crate::models::Vertex;
#[derive(PartialEq, Eq)]
struct DistanceOrderedVertex {
distance: u32,
vertex: Vertex,
}
impl PartialOrd for DistanceOrderedVertex {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.distance.cmp(&other.distance))
}
}
impl Ord for DistanceOrderedVertex {
fn cmp(&self, other: &Self) -> Ordering {
other.distance.cmp(&self.distance)
}
}
// TODO: Maybe introduce a return struct type for Dijkstra's algorithm?
// TODO: Maybe variant of Dijkstra's algorithm without predecessors?
pub fn dijkstra(graph: &Graph, source: Vertex) -> (Vec<Option<u32>>, Vec<Option<Vertex>>) {
let mut distances = vec![None; graph.vertex_count()];
let mut predecessors = vec![None; graph.vertex_count()];
let mut heap = BinaryHeap::new();
distances[source.0] = Some(0);
heap.push(DistanceOrderedVertex {
vertex: source,
distance: 0,
});
while let Some(v) = heap.pop() {
// TODO: Simplify with a neighbor iterator.
// Finds the first neighbor of v.
let Some(mut incidence) = graph.incidence_headers[v.vertex.0].first_incidence else {
break;
};
loop {
// Processes one neighbor of v.
let neighbor = graph.incidence_vertices[incidence.0];
// TODO: Add a way to provide custom edge weights for Dijkstra's algorithm.
let edge_weight = 1;
let new_distance = distances[v.vertex.0].unwrap() + edge_weight;
if match distances[neighbor.0] {
None => true,
Some(old_distance) if old_distance > new_distance => true,
_ => false,
} {
distances[neighbor.0] = Some(new_distance);
predecessors[neighbor.0] = Some(v.vertex);
heap.push(DistanceOrderedVertex {
vertex: neighbor,
distance: new_distance,
});
}
// Finds next neighbor of v.
let Some(next) = graph.next_incidences[incidence.0] else {
break;
};
incidence = next;
}
}
(distances, predecessors)
}