Skip to content

Commit c4c1bd7

Browse files
committed
feat: impl of ByRandom
1 parent 6eb1289 commit c4c1bd7

File tree

6 files changed

+471
-314
lines changed

6 files changed

+471
-314
lines changed

Cargo.lock

Lines changed: 17 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ keywords = ["dsu", "disjoint-set", "union-find", "no-std"]
1313
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1414

1515
[dependencies]
16+
rand = { version = "0.9.2", default-features = false }
1617

1718
[dev-dependencies]
18-
heapless = "0.7.16"
19+
heapless = "0.7.16"

src/lib.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,15 @@
6868

6969
pub mod quickfind;
7070
pub mod quickunion;
71+
pub mod rng;
7172

7273
use core::marker::PhantomData;
7374
use core::ops::AddAssign;
7475

76+
use rand::RngCore;
77+
7578
pub use crate::quickfind::QuickFind;
79+
use crate::quickunion::Heuristic;
7680
pub use crate::quickunion::QuickUnion;
7781
pub use crate::quickunion::{ByRank, BySize, Unweighted};
7882

@@ -149,13 +153,14 @@ where
149153
{
150154
representative: A::RepresentativeContainer<'a, T, N>,
151155
heuristic: A::HeuristicContainer<'a, N>,
156+
rng: A::RngKind<'a>,
152157
algorithm: PhantomData<A>,
153158
}
154159

155160
impl<'a, A, T, const N: usize> UnionFind<'a, A, T, N>
156161
where
157162
T: VertexType,
158-
A: AlgorithmContainer + Union<T> + Find<T> + Connected<T>,
163+
A: AlgorithmContainer + Union<T, A::HeuristicKind<'a>> + Find<T> + Connected<T>,
159164
{
160165
/// Checks whether 2 nodes are connected to each other
161166
pub fn connected(&mut self, a: T::IdentifierType, b: T::IdentifierType) -> bool {
@@ -170,14 +175,15 @@ where
170175
/// Unions 2 node. If those 2 nodes are already part of the same component
171176
/// then this does nothing
172177
pub fn union_sets(&mut self, a: T::IdentifierType, b: T::IdentifierType) {
173-
A::union_sets(self.representative.as_mut(), self.heuristic.as_mut(), a, b)
174-
}
175-
176-
/// Gets the representative slice
177-
pub fn representative(&self) -> &A::RepresentativeContainer<'a, T, N> {
178-
&self.representative
178+
A::union_sets(
179+
self.representative.as_mut(),
180+
self.heuristic.as_mut(),
181+
a,
182+
b,
183+
self.rng.as_mut(),
184+
)
179185
}
180-
186+
/// Gets the representative slice pub fn representative(&self) -> &A::RepresentativeContainer<'a, T, N> { &self.representative }
181187
/// Gets the heuristic slice
182188
pub fn heuristic(&self) -> &A::HeuristicContainer<'a, N> {
183189
&self.heuristic
@@ -186,6 +192,8 @@ where
186192

187193
/// This trait represents the kind of containers that is required for a particular algorithm to function
188194
pub trait AlgorithmContainer {
195+
type HeuristicKind<'a>: Heuristic<RngProvider = Self::RngKind<'a>>;
196+
189197
/// Any kind of contiguous container
190198
///
191199
/// # Examples
@@ -199,35 +207,30 @@ pub trait AlgorithmContainer {
199207
/// # Examples
200208
/// - `[T; N]`
201209
/// - `heaples::Vec<T, N>`
202-
type RepresentativeContainer<'a, R: VertexType + 'a, const N: usize>: AsRef<[R]> + AsMut<[R]>;
210+
type RepresentativeContainer<'a, V: VertexType + 'a, const N: usize>: AsRef<[V]> + AsMut<[V]>;
211+
212+
/// Any kind of RNG
213+
type RngKind<'a>: RngCore + AsMut<Self::RngKind<'a>>;
203214
}
204215

205216
/// Union operation
206-
pub trait Union<T>
207-
where
208-
T: VertexType,
209-
{
217+
pub trait Union<T: VertexType, H: Heuristic> {
210218
fn union_sets(
211219
representative: &mut [T],
212220
heuristic: &mut [usize],
213221
a: T::IdentifierType,
214222
b: T::IdentifierType,
223+
rng: &mut H::RngProvider,
215224
);
216225
}
217226

218227
/// Find operation
219-
pub trait Find<T>
220-
where
221-
T: VertexType,
222-
{
228+
pub trait Find<T: VertexType> {
223229
fn find(representative: &mut [T], a: T::IdentifierType) -> T;
224230
}
225231

226232
/// Connected operation
227-
pub trait Connected<T>
228-
where
229-
T: VertexType,
230-
{
233+
pub trait Connected<T: VertexType> {
231234
fn connected(representative: &mut [T], a: T::IdentifierType, b: T::IdentifierType) -> bool;
232235
}
233236

src/quickfind.rs

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,48 @@
11
//! Quick Find implementations
22
3-
use crate::{AlgorithmContainer, Connected, Find, Union, UnionFind, VertexType};
3+
use core::marker::PhantomData;
4+
5+
use crate::{
6+
quickunion::Heuristic, rng::PhantomRng, AlgorithmContainer, Borrowed, Connected, Find, Owned,
7+
Union, UnionFind, VertexType,
8+
};
49

510
/// [`QuickFind`] algorithm
611
#[derive(Debug, Default)]
7-
pub struct QuickFind<const IS_SLICE: bool = false>;
12+
pub struct QuickFind<K = Owned> {
13+
_p: PhantomData<K>,
14+
}
15+
16+
pub struct NoHeuristic;
17+
18+
impl Heuristic for NoHeuristic {
19+
type RngProvider = PhantomRng;
20+
21+
fn handle_decision<T>(
22+
_a: T::IdentifierType,
23+
_b: T::IdentifierType,
24+
_heuristic: &mut [usize],
25+
_representative: &mut [T],
26+
_r: &mut Self::RngProvider,
27+
) where
28+
T: VertexType,
29+
{
30+
unreachable!("Should not be called!")
31+
}
32+
}
833

9-
impl AlgorithmContainer for QuickFind<false> {
34+
impl AlgorithmContainer for QuickFind<Owned> {
35+
type HeuristicKind<'a> = NoHeuristic;
1036
type HeuristicContainer<'a, const N: usize> = [usize; 0];
1137
type RepresentativeContainer<'a, R: VertexType + 'a, const N: usize> = [R; N];
38+
type RngKind<'a> = PhantomRng;
1239
}
1340

14-
impl AlgorithmContainer for QuickFind<true> {
41+
impl AlgorithmContainer for QuickFind<Borrowed> {
42+
type HeuristicKind<'a> = NoHeuristic;
1543
type HeuristicContainer<'a, const N: usize> = [usize; 0];
1644
type RepresentativeContainer<'a, R: VertexType + 'a, const N: usize> = &'a mut [R];
45+
type RngKind<'a> = PhantomRng;
1746
}
1847

1948
macro_rules! generate_default_ctor_quickfind {
@@ -32,14 +61,15 @@ macro_rules! generate_default_ctor_quickfind {
3261
representative,
3362
heuristic: [0; 0],
3463
algorithm: Default::default(),
64+
rng: PhantomRng
3565
}
3666
}
3767
}
3868
)*
3969
};
4070
}
4171

42-
impl<'a, T, const N: usize> UnionFind<'a, QuickFind<true>, T, N>
72+
impl<'a, T, const N: usize> UnionFind<'a, QuickFind<Borrowed>, T, N>
4373
where
4474
T: VertexType,
4575
{
@@ -48,11 +78,12 @@ where
4878
representative,
4979
heuristic: [0; 0],
5080
algorithm: Default::default(),
81+
rng: PhantomRng,
5182
}
5283
}
5384
}
5485

55-
impl<T, const IS_SLICE: bool> Connected<T> for QuickFind<IS_SLICE>
86+
impl<T, K> Connected<T> for QuickFind<K>
5687
where
5788
T: VertexType,
5889
Self: Find<T>,
@@ -62,7 +93,7 @@ where
6293
}
6394
}
6495

65-
impl<T, const IS_SLICE: bool> Union<T> for QuickFind<IS_SLICE>
96+
impl<T, K> Union<T, NoHeuristic> for QuickFind<K>
6697
where
6798
T: VertexType,
6899
Self: Find<T>,
@@ -72,6 +103,7 @@ where
72103
_heuristic: &mut [usize],
73104
a: T::IdentifierType,
74105
b: T::IdentifierType,
106+
_r: &mut PhantomRng,
75107
) {
76108
let root_a = Self::find(representative, a);
77109
let root_b = Self::find(representative, b);
@@ -83,7 +115,7 @@ where
83115
}
84116
}
85117

86-
impl<T, const IS_SLICE: bool> Find<T> for QuickFind<IS_SLICE>
118+
impl<T, K> Find<T> for QuickFind<K>
87119
where
88120
T: VertexType,
89121
{
@@ -97,7 +129,7 @@ generate_default_ctor_quickfind!(u8, u16, u32, u64, usize);
97129

98130
#[cfg(test)]
99131
mod tests {
100-
use crate::{tests::CityVertex, QuickFind, UnionFind};
132+
use crate::{rng::PhantomRng, tests::CityVertex, Borrowed, QuickFind, UnionFind};
101133
use core::{mem, panic};
102134

103135
#[test]
@@ -113,7 +145,7 @@ mod tests {
113145
#[test]
114146
fn test_qf_slice() {
115147
let mut representative = (0..10).collect::<heapless::Vec<_, 10>>();
116-
let mut uf = UnionFind::<QuickFind<true>, u32, 10>::new(representative.as_mut());
148+
let mut uf = UnionFind::<QuickFind<Borrowed>, u32, 10>::new(representative.as_mut());
117149
uf.union_sets(4, 3);
118150
uf.union_sets(3, 8);
119151
uf.union_sets(6, 5);
@@ -137,6 +169,7 @@ mod tests {
137169
representative: cities,
138170
heuristic: [0; 0],
139171
algorithm: Default::default(),
172+
rng: PhantomRng,
140173
})
141174
}
142175
}
@@ -169,7 +202,7 @@ mod tests {
169202
);
170203
assert_eq!(
171204
mem::size_of::<&'_ [u32]>(),
172-
mem::size_of::<UnionFind::<'_, QuickFind<true>, u32, 10>>()
205+
mem::size_of::<UnionFind::<'_, QuickFind<Borrowed>, u32, 10>>()
173206
);
174207
assert_eq!(
175208
mem::size_of::<[CityVertex<'_>; 10]>(),

0 commit comments

Comments
 (0)