use crate::wavelet_tree_pointer_based::*;
use crate::WaveletTree;
use bio::data_structures::rank_select::RankSelect;
use bv::BitVec;
pub trait GraphWithWT {
fn neighbor(&mut self, node: u64, nth_neighbor: u64) -> Option<u64>;
fn reverse_neigbor(&mut self, node: u64, nth_reverse_neighbor: u64) -> Option<u64>;
}
pub struct WaveletTreeGraph {
bitmap: Option<RankSelect>,
wavelet_tree: Option<WaveletTreePointer<u64>>,
}
pub struct WTGraphBuilder {
size: usize,
bit_vec: Vec<bool>,
list: Vec<u64>,
}
impl WTGraphBuilder {
pub fn add_edge<'a>(
&'a mut self,
start_node: u64,
end_node: u64,
) -> Result<&'a mut WTGraphBuilder, &'static str> {
if self.size <= start_node as usize {
return Err("start_node not found in graph");
}
if self.size <= end_node as usize {
return Err("end_node not found in graph");
}
let upper_insert_bound = select(&self.bit_vec, start_node + 1);
if upper_insert_bound != None {
self.bit_vec
.insert((upper_insert_bound.unwrap()) as usize, false);
self.list.insert(
(upper_insert_bound.unwrap() - start_node - 1) as usize,
end_node,
);
}
else {
self.bit_vec.push(false);
self.list.push(end_node);
}
return Ok(self);
}
pub fn to_graph(&self) -> WaveletTreeGraph {
let bitmap = Some(bool_vec_to_rankselect(&self.bit_vec));
let wavelet_tree = Some(WaveletTreePointer::new(self.list.clone()));
WaveletTreeGraph {
bitmap,
wavelet_tree,
}
}
pub fn with_capacities(size: usize) -> Self {
WTGraphBuilder {
bit_vec: vec![true; size],
list: vec![],
size,
}
}
}
impl GraphWithWT for WaveletTreeGraph {
fn neighbor(&mut self, node: u64, nth_neighbor: u64) -> Option<u64> {
let l = self.bitmap.as_mut().unwrap().select(node + 1);
if l.is_none() {
return None;
}
let c = self.bitmap.as_mut().unwrap().select(node + 2);
if c.is_none() {
return None;
}
if l.unwrap() >= c.unwrap() - nth_neighbor {
return None;
}
if self.bitmap.as_mut().unwrap().rank_1(l.unwrap() + 1) > Some(node + 1) {
return None;
}
self.wavelet_tree
.as_mut()
.unwrap()
.access(l.unwrap() + nth_neighbor - (node + 1))
}
fn reverse_neigbor(&mut self, node: u64, nth_reverse_neighbor: u64) -> Option<u64> {
let p = self
.wavelet_tree
.as_mut()
.unwrap()
.select(node, nth_reverse_neighbor);
if p != None {
let index_in_bitmap = self.bitmap.as_mut().unwrap().select_0(p.unwrap() + 1);
if index_in_bitmap != None {
let result = self.bitmap.as_mut().unwrap().rank(index_in_bitmap.unwrap());
if result != None {
return Some(result.unwrap() - 1);
}
return None;
}
index_in_bitmap
} else {
p
}
}
}
fn select(bit_vec: &Vec<bool>, n: u64) -> Option<u64> {
let mut i = 0;
let mut counter = 0;
loop {
if i >= bit_vec.len() {
return None;
}
if bit_vec[i] == true {
if counter == n {
return Some(i as u64);
}
counter += 1;
}
i += 1;
}
}
fn bool_vec_to_rankselect(bit_vec: &Vec<bool>) -> RankSelect {
let mut bits: BitVec<u8> = BitVec::new();
for b in bit_vec {
bits.push(*b);
}
RankSelect::new(bits, 1)
}
#[cfg(test)]
mod tests {
use super::*;
fn create_sample_graph() -> WaveletTreeGraph {
let w_builder = fill_wt_builder();
w_builder.to_graph()
}
fn fill_wt_builder() -> WTGraphBuilder {
let mut w_builder = WTGraphBuilder::with_capacities(6);
w_builder
.add_edge(0, 1)
.expect("Could not add edge to graph");
w_builder
.add_edge(0, 3)
.expect("Could not add edge to graph");
w_builder
.add_edge(1, 0)
.expect("Could not add edge to graph");
w_builder
.add_edge(1, 3)
.expect("Could not add edge to graph");
w_builder
.add_edge(1, 2)
.expect("Could not add edge to graph");
w_builder
.add_edge(3, 2)
.expect("Could not add edge to graph");
w_builder
.add_edge(4, 0)
.expect("Could not add edge to graph");
w_builder
.add_edge(4, 3)
.expect("Could not add edge to graph");
w_builder
}
#[test]
fn test_add_edge() {
let graph = fill_wt_builder();
assert_eq!(graph.list, vec![1, 3, 0, 3, 2, 2, 0, 3]);
assert_eq!(
graph.bit_vec,
vec![
true, false, false, true, false, false, false, true, true, false, true, false,
false, true
]
);
}
#[test]
fn test_neighbor() {
let mut graph = create_sample_graph();
assert_eq!(None, graph.neighbor(0, 3));
assert_eq!(Some(3), graph.neighbor(0, 2));
assert_eq!(Some(1), graph.neighbor(0, 1));
assert_eq!(None, graph.neighbor(1, 4));
assert_eq!(Some(2), graph.neighbor(1, 3));
assert_eq!(Some(3), graph.neighbor(1, 2));
assert_eq!(Some(0), graph.neighbor(1, 1));
assert_eq!(None, graph.neighbor(2, 0));
assert_eq!(None, graph.neighbor(3, 2));
assert_eq!(Some(2), graph.neighbor(3, 1));
assert_eq!(None, graph.neighbor(4, 3));
assert_eq!(Some(3), graph.neighbor(4, 2));
assert_eq!(Some(0), graph.neighbor(4, 1));
assert_eq!(None, graph.neighbor(5, 1));
}
#[test]
fn test_reverse_neighbor() {
let mut graph = create_sample_graph();
assert_eq!(Some(1), graph.reverse_neigbor(0, 1));
assert_eq!(Some(4), graph.reverse_neigbor(0, 2));
assert_eq!(None, graph.reverse_neigbor(0, 3));
assert_eq!(Some(0), graph.reverse_neigbor(1, 1));
assert_eq!(None, graph.reverse_neigbor(1, 2));
assert_eq!(Some(1), graph.reverse_neigbor(2, 1));
assert_eq!(Some(3), graph.reverse_neigbor(2, 2));
assert_eq!(None, graph.reverse_neigbor(2, 3));
assert_eq!(Some(0), graph.reverse_neigbor(3, 1));
assert_eq!(Some(1), graph.reverse_neigbor(3, 2));
assert_eq!(Some(4), graph.reverse_neigbor(3, 3));
assert_eq!(None, graph.reverse_neigbor(3, 4));
assert_eq!(None, graph.reverse_neigbor(4, 1));
assert_eq!(None, graph.reverse_neigbor(5, 1));
}
}