Skip to content

Commit 1f361ae

Browse files
committed
Added 'proxy::EdgeWeightMap'
'DijkstraShortestPaths', 'Spfs', and 'Connected::*' now only take graphs with integer weights. EdgeWeightMap is used to wrap other graphs. Simplified 'Graph' (and other traits) method lifetime requirements.
1 parent fb5742b commit 1f361ae

18 files changed

+378
-303
lines changed

src/algo/dijkstra_shortest_paths.rs

+23-55
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,38 @@
11
use crate::core::{property::HasVertex, Edge, Graph};
2-
use num_traits::{PrimInt, Unsigned};
2+
use num_traits::{PrimInt, Unsigned, Zero};
33
use std::borrow::Borrow;
44

55
/// [Dijkstra's shortest paths algorithm](https://mathworld.wolfram.com/DijkstrasAlgorithm.html)
6-
pub struct DijkstraShortestPaths<'a, G, W>
6+
pub struct DijkstraShortestPaths<'a, G>
77
where
88
G: 'a + Graph,
9-
W: PrimInt + Unsigned,
9+
G::EdgeWeight: PrimInt + Unsigned,
1010
{
1111
graph: &'a G,
1212
visited: Vec<G::Vertex>,
1313
// We keep it sorted with the lowest weight at the end for efficiency.
14-
queue: Vec<(W, (G::Vertex, G::Vertex, G::EdgeWeightRef<'a>))>,
15-
get_distance: fn(&G::EdgeWeight) -> W,
14+
queue: Vec<(G::EdgeWeight, (G::Vertex, G::Vertex, G::EdgeWeightRef<'a>))>,
1615
}
1716

18-
impl<'a, G, W> DijkstraShortestPaths<'a, G, W>
17+
impl<'a, G> DijkstraShortestPaths<'a, G>
1918
where
2019
G: 'a + Graph,
21-
W: PrimInt + Unsigned,
20+
G::EdgeWeight: PrimInt + Unsigned,
2221
{
23-
pub fn new(graph: &'a G, get_distance: fn(&G::EdgeWeight) -> W) -> Self
22+
pub fn new(graph: &'a G) -> Self
2423
where
2524
G: HasVertex,
2625
{
2726
let mut dijk = Self {
2827
graph,
2928
visited: Vec::new(),
3029
queue: Vec::new(),
31-
get_distance,
3230
};
33-
dijk.visit(graph.get_vertex(), W::zero());
31+
dijk.visit(graph.get_vertex(), G::EdgeWeight::zero());
3432
dijk
3533
}
3634

37-
fn visit(&mut self, v: G::Vertex, w: W)
35+
fn visit(&mut self, v: G::Vertex, w: G::EdgeWeight)
3836
{
3937
self.visited.push(v);
4038
let visited = &self.visited;
@@ -44,7 +42,7 @@ where
4442

4543
for (sink, weight) in edges
4644
{
47-
let new_weight = w + (self.get_distance)(weight.borrow());
45+
let new_weight = w + *weight.borrow();
4846
if let Some((old_weight, old_edge)) = self
4947
.queue
5048
.iter_mut()
@@ -66,42 +64,25 @@ where
6664

6765
/// Returns the vertices reachable from the designated vertex and the
6866
/// weighted distance to them
69-
pub fn distances(
70-
graph: &'a G,
71-
get_distance: fn(&G::EdgeWeight) -> W,
72-
) -> impl 'a + Iterator<Item = (G::Vertex, W)>
67+
pub fn distances(graph: &'a G) -> impl 'a + Iterator<Item = (G::Vertex, G::EdgeWeight)>
7368
where
7469
G: HasVertex,
75-
W: 'a,
7670
{
77-
let mut distances = vec![(graph.get_vertex(), W::zero())];
71+
let mut distances = vec![(graph.get_vertex(), G::EdgeWeight::zero())];
7872

79-
DijkstraShortestPaths::new(graph, get_distance).map(move |(so, si, w)| {
73+
DijkstraShortestPaths::new(graph).map(move |(so, si, w)| {
8074
let dist = distances.iter().find(|(v, _)| so == *v).unwrap().1;
81-
let new_dist = dist + get_distance(w.borrow());
75+
let new_dist = dist + *w.borrow();
8276
distances.push((si, new_dist));
8377
(si, new_dist)
8478
})
8579
}
8680
}
8781

88-
impl<'a, G> DijkstraShortestPaths<'a, G, G::EdgeWeight>
82+
impl<'a, G> Iterator for DijkstraShortestPaths<'a, G>
8983
where
9084
G: 'a + Graph,
9185
G::EdgeWeight: PrimInt + Unsigned,
92-
{
93-
pub fn new_simple(graph: &'a G) -> Self
94-
where
95-
G: HasVertex,
96-
{
97-
Self::new(graph, Clone::clone)
98-
}
99-
}
100-
101-
impl<'a, G, W> Iterator for DijkstraShortestPaths<'a, G, W>
102-
where
103-
G: 'a + Graph,
104-
W: PrimInt + Unsigned,
10586
{
10687
type Item = (G::Vertex, G::Vertex, G::EdgeWeightRef<'a>);
10788

@@ -118,46 +99,33 @@ where
11899
/// Shortest-Path-First search
119100
///
120101
/// next() doesn't return the starting vertex.
121-
pub struct Spfs<'a, G, W>
102+
pub struct Spfs<'a, G>
122103
where
123104
G: 'a + Graph,
124-
W: PrimInt + Unsigned,
105+
G::EdgeWeight: PrimInt + Unsigned,
125106
{
126-
dijk: DijkstraShortestPaths<'a, G, W>,
107+
dijk: DijkstraShortestPaths<'a, G>,
127108
}
128109

129-
impl<'a, G, W> Spfs<'a, G, W>
110+
impl<'a, G> Spfs<'a, G>
130111
where
131112
G: 'a + Graph,
132-
W: PrimInt + Unsigned,
113+
G::EdgeWeight: PrimInt + Unsigned,
133114
{
134-
pub fn new(graph: &'a G, get_weight: fn(&G::EdgeWeight) -> W) -> Self
115+
pub fn new(graph: &'a G) -> Self
135116
where
136117
G: HasVertex,
137118
{
138119
Self {
139-
dijk: DijkstraShortestPaths::new(graph, get_weight),
120+
dijk: DijkstraShortestPaths::new(graph),
140121
}
141122
}
142123
}
143124

144-
impl<'a, G> Spfs<'a, G, G::EdgeWeight>
125+
impl<'a, G> Iterator for Spfs<'a, G>
145126
where
146127
G: 'a + Graph,
147128
G::EdgeWeight: PrimInt + Unsigned,
148-
{
149-
pub fn new_simple(graph: &'a G) -> Self
150-
where
151-
G: HasVertex,
152-
{
153-
Self::new(graph, Clone::clone)
154-
}
155-
}
156-
157-
impl<'a, G, W> Iterator for Spfs<'a, G, W>
158-
where
159-
G: 'a + Graph,
160-
W: PrimInt + Unsigned,
161129
{
162130
type Item = G::Vertex;
163131

src/common/adjacency_list/impl_graph.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ where
2525
self.vertices.iter().enumerate().map(|(v, (w, _))| (v, w))
2626
}
2727

28-
fn edges_between<'a: 'b, 'b>(
29-
&'a self,
30-
source: impl 'b + Borrow<Self::Vertex>,
31-
sink: impl 'b + Borrow<Self::Vertex>,
32-
) -> impl 'b + Iterator<Item = Self::EdgeWeightRef<'a>>
28+
fn edges_between(
29+
&self,
30+
source: impl Borrow<Self::Vertex>,
31+
sink: impl Borrow<Self::Vertex>,
32+
) -> impl Iterator<Item = Self::EdgeWeightRef<'_>>
3333
{
3434
let source = source.borrow().clone();
3535
let sink = sink.borrow().clone();
@@ -75,19 +75,19 @@ where
7575
{
7676
fn all_vertices_weighted_mut(
7777
&mut self,
78-
) -> impl '_ + Iterator<Item = (Self::Vertex, &mut Self::VertexWeight)>
78+
) -> impl Iterator<Item = (Self::Vertex, &mut Self::VertexWeight)>
7979
{
8080
self.vertices
8181
.iter_mut()
8282
.enumerate()
8383
.map(|(v, (w, _))| (v, w))
8484
}
8585

86-
fn edges_between_mut<'a: 'b, 'b>(
87-
&'a mut self,
88-
source: impl 'b + Borrow<Self::Vertex>,
89-
sink: impl 'b + Borrow<Self::Vertex>,
90-
) -> impl 'b + Iterator<Item = &'a mut Self::EdgeWeight>
86+
fn edges_between_mut(
87+
&mut self,
88+
source: impl Borrow<Self::Vertex>,
89+
sink: impl Borrow<Self::Vertex>,
90+
) -> impl Iterator<Item = &mut Self::EdgeWeight>
9191
{
9292
let source = source.borrow().clone();
9393
let sink = sink.borrow().clone();

src/core/graph.rs

+27-30
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,18 @@ pub trait Graph
9191
///
9292
/// If the graph is undirected, returns all edges connecting the two
9393
/// vertices. I.e. all edges where e == (v1,v2,_) or e == (v2,v1,_)
94-
fn edges_between<'a: 'b, 'b>(
95-
&'a self,
96-
source: impl 'b + Borrow<Self::Vertex>,
97-
sink: impl 'b + Borrow<Self::Vertex>,
98-
) -> impl 'b + Iterator<Item = Self::EdgeWeightRef<'a>>;
94+
fn edges_between(
95+
&self,
96+
source: impl Borrow<Self::Vertex>,
97+
sink: impl Borrow<Self::Vertex>,
98+
) -> impl Iterator<Item = Self::EdgeWeightRef<'_>>;
9999

100100
// Optional methods
101101

102102
/// Returns copies of all current edges in the graph.
103103
fn all_edges(
104104
&self,
105-
) -> impl '_ + Iterator<Item = (Self::Vertex, Self::Vertex, Self::EdgeWeightRef<'_>)>
105+
) -> impl Iterator<Item = (Self::Vertex, Self::Vertex, Self::EdgeWeightRef<'_>)>
106106
{
107107
let mut finished = Vec::new();
108108
self.all_vertices()
@@ -124,7 +124,7 @@ pub trait Graph
124124
})
125125
}
126126

127-
fn all_vertices(&self) -> impl '_ + Iterator<Item = Self::Vertex>
127+
fn all_vertices(&self) -> impl Iterator<Item = Self::Vertex>
128128
{
129129
self.all_vertices_weighted().map(|(v, _)| v)
130130
}
@@ -146,7 +146,7 @@ pub trait Graph
146146
iter.into_iter().all(|v| self.contains_vertex(v))
147147
}
148148

149-
fn all_vertex_weights(&self) -> impl '_ + Iterator<Item = &Self::VertexWeight>
149+
fn all_vertex_weights(&self) -> impl Iterator<Item = &Self::VertexWeight>
150150
{
151151
self.all_vertices_weighted().map(|(_, w)| w)
152152
}
@@ -156,10 +156,10 @@ pub trait Graph
156156
///
157157
/// If the graph is undirected, is semantically equivalent to
158158
/// `edges_incident_on`.
159-
fn edges_sourced_in<'a: 'b, 'b>(
160-
&'a self,
161-
v: impl 'b + Borrow<Self::Vertex>,
162-
) -> impl 'b + Iterator<Item = (Self::Vertex, Self::EdgeWeightRef<'a>)>
159+
fn edges_sourced_in(
160+
&self,
161+
v: impl Borrow<Self::Vertex>,
162+
) -> impl Iterator<Item = (Self::Vertex, Self::EdgeWeightRef<'_>)>
163163
{
164164
self.all_vertices().flat_map(move |v2| {
165165
self.edges_between(v.borrow().clone(), v2.borrow().clone())
@@ -172,10 +172,10 @@ pub trait Graph
172172
///
173173
/// If the graph is undirected, is semantically equivalent to
174174
/// `edges_incident_on`.
175-
fn edges_sinked_in<'a: 'b, 'b>(
176-
&'a self,
177-
v: impl 'b + Borrow<Self::Vertex>,
178-
) -> impl 'b + Iterator<Item = (Self::Vertex, Self::EdgeWeightRef<'a>)>
175+
fn edges_sinked_in(
176+
&self,
177+
v: impl Borrow<Self::Vertex>,
178+
) -> impl Iterator<Item = (Self::Vertex, Self::EdgeWeightRef<'_>)>
179179
{
180180
self.all_vertices().flat_map(move |v2| {
181181
self.edges_between(v2.borrow().clone(), v.borrow().clone())
@@ -187,10 +187,10 @@ pub trait Graph
187187
/// on the given vertex.
188188
///
189189
/// If the graph is directed, edge directions are ignored.
190-
fn edges_incident_on<'a: 'b, 'b>(
191-
&'a self,
192-
v: impl 'b + Borrow<Self::Vertex>,
193-
) -> impl 'b + Iterator<Item = (Self::Vertex, Self::EdgeWeightRef<'a>)>
190+
fn edges_incident_on(
191+
&self,
192+
v: impl Borrow<Self::Vertex>,
193+
) -> impl Iterator<Item = (Self::Vertex, Self::EdgeWeightRef<'_>)>
194194
{
195195
self.edges_sourced_in(v.borrow().clone()).chain(
196196
self.edges_sinked_in(v.borrow().clone())
@@ -200,10 +200,7 @@ pub trait Graph
200200

201201
/// Returns any vertices connected to the given one with an edge regardless
202202
/// of direction.
203-
fn vertex_neighbors<'a: 'b, 'b>(
204-
&'a self,
205-
v: impl 'b + Borrow<Self::Vertex>,
206-
) -> impl 'b + Iterator<Item = Self::Vertex>
203+
fn vertex_neighbors(&self, v: impl Borrow<Self::Vertex>) -> impl Iterator<Item = Self::Vertex>
207204
{
208205
self.all_vertices()
209206
.filter(move |other| self.neighbors(v.borrow(), other.borrow()))
@@ -234,13 +231,13 @@ pub trait GraphMut: Graph
234231
{
235232
fn all_vertices_weighted_mut(
236233
&mut self,
237-
) -> impl '_ + Iterator<Item = (Self::Vertex, &mut Self::VertexWeight)>;
234+
) -> impl Iterator<Item = (Self::Vertex, &mut Self::VertexWeight)>;
238235

239-
fn edges_between_mut<'a: 'b, 'b>(
240-
&'a mut self,
241-
source: impl 'b + Borrow<Self::Vertex>,
242-
sink: impl 'b + Borrow<Self::Vertex>,
243-
) -> impl 'b + Iterator<Item = &'a mut Self::EdgeWeight>;
236+
fn edges_between_mut(
237+
&mut self,
238+
source: impl Borrow<Self::Vertex>,
239+
sink: impl Borrow<Self::Vertex>,
240+
) -> impl Iterator<Item = &mut Self::EdgeWeight>;
244241

245242
// Optional methods
246243

0 commit comments

Comments
 (0)