mirror of
https://github.com/pfzetto/rebacs
synced 2024-11-26 04:59:35 +01:00
replaced dijkstra-ish algorithm with BFS
This commit is contained in:
parent
fd5d42ea61
commit
92090ffc3d
1 changed files with 25 additions and 56 deletions
|
@ -1,10 +1,9 @@
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::{BTreeSet, BinaryHeap, HashSet},
|
collections::{BTreeSet, HashSet},
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
ops::Deref,
|
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,12 +28,6 @@ pub struct Node {
|
||||||
pub edges_out: RwLock<Vec<Arc<Node>>>,
|
pub edges_out: RwLock<Vec<Arc<Node>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
struct Distanced<T> {
|
|
||||||
distance: u32,
|
|
||||||
data: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RelationGraph {
|
pub struct RelationGraph {
|
||||||
nodes: RwLock<BTreeSet<Arc<Node>>>,
|
nodes: RwLock<BTreeSet<Arc<Node>>>,
|
||||||
|
@ -112,6 +105,7 @@ impl RelationGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// checks if there is a path between src and dst using BFS
|
||||||
pub async fn has_recursive<'a>(
|
pub async fn has_recursive<'a>(
|
||||||
&self,
|
&self,
|
||||||
src: impl Into<NodeId>,
|
src: impl Into<NodeId>,
|
||||||
|
@ -127,34 +121,40 @@ impl RelationGraph {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
let src_neighbors = src
|
let mut distance = 1;
|
||||||
|
|
||||||
|
let mut neighbors = src
|
||||||
.edges_out
|
.edges_out
|
||||||
.read()
|
.read()
|
||||||
.await
|
.await
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| Distanced::one(x.clone()))
|
.cloned()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut q: BinaryHeap<Distanced<Arc<Node>>> = BinaryHeap::from(src_neighbors);
|
|
||||||
let mut visited: HashSet<Arc<Node>> = HashSet::new();
|
let mut visited: HashSet<Arc<Node>> = HashSet::new();
|
||||||
|
|
||||||
while let Some(distanced) = q.pop() {
|
while !neighbors.is_empty() {
|
||||||
if distanced.id == dst {
|
let mut next_neighbors = vec![];
|
||||||
|
for neighbor in neighbors {
|
||||||
|
if distance > 1 && visited.contains(&neighbor) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if neighbor.id == dst {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if let Some(limit) = limit {
|
if let Some(limit) = limit {
|
||||||
if distanced.distance() > limit {
|
if distance > limit {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for neighbor in distanced.edges_out.read().await.iter() {
|
let mut node_neighbors = neighbor.edges_out.read().await.clone();
|
||||||
if !visited.contains(neighbor) {
|
next_neighbors.append(&mut node_neighbors);
|
||||||
q.push(Distanced::new(neighbor.clone(), distanced.distance() + 1))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visited.insert(distanced.clone());
|
visited.insert(neighbor);
|
||||||
|
}
|
||||||
|
neighbors = next_neighbors;
|
||||||
|
distance += 1;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -292,37 +292,6 @@ impl Hash for Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Distanced<T> {
|
|
||||||
pub fn new(data: T, distance: u32) -> Self {
|
|
||||||
Self { distance, data }
|
|
||||||
}
|
|
||||||
pub fn one(data: T) -> Self {
|
|
||||||
Self { distance: 1, data }
|
|
||||||
}
|
|
||||||
pub fn distance(&self) -> u32 {
|
|
||||||
self.distance
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Deref for Distanced<T> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: PartialEq> PartialOrd for Distanced<T> {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
||||||
self.distance.partial_cmp(&other.distance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: Eq> Ord for Distanced<T> {
|
|
||||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
|
||||||
self.distance.cmp(&other.distance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(&str, &str)> for NodeId {
|
impl From<(&str, &str)> for NodeId {
|
||||||
fn from(value: (&str, &str)) -> Self {
|
fn from(value: (&str, &str)) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
Loading…
Reference in a new issue