From 75b47aeefd1da9e9f8be5af743bea841e69d3590 Mon Sep 17 00:00:00 2001 From: Aziz Kayumov Date: Wed, 4 Oct 2023 11:15:05 +0900 Subject: [PATCH 1/2] findmax random test #12 --- src/lib.rs | 55 ++++-------------------------------- src/node.rs | 4 +-- tests/test_findmax_random.rs | 47 ++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 52 deletions(-) create mode 100644 tests/test_findmax_random.rs diff --git a/src/lib.rs b/src/lib.rs index dc50993..a74cd1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,12 +2,9 @@ mod node; mod path; mod splay; - -use splay::update_max; - use crate::{ node::{Node, Parent}, - splay::splay, + splay::{splay, update_max}, }; pub struct LinkCutTree { @@ -21,6 +18,10 @@ impl LinkCutTree { Self { forest: nodes } } + pub fn set_weight(&mut self, v: usize, weight: f64) { + self.forest[v].weight = weight; + } + // Constructs a path from a node to the root of the tree. pub fn access(&mut self, v: usize) { splay(&mut self.forest, v); @@ -88,7 +89,6 @@ impl LinkCutTree { #[cfg(test)] mod tests { use crate::node::Parent; - use rand::{seq::SliceRandom, Rng, SeedableRng}; #[test] pub fn access_base_case() { @@ -443,49 +443,4 @@ mod tests { assert_eq!(lctree.findmax(1), 0); assert_eq!(lctree.findmax(0), 0); } - - fn create_random_tree(n: usize, seed: u64) -> (Vec<(usize, usize)>, Vec, Vec) { - let mut rng = rand::rngs::StdRng::seed_from_u64(seed); - - let mut edges = Vec::new(); - let mut weights: Vec = (0..n).map(|i| i as f64).collect(); - weights.shuffle(&mut rng); - - let mut ground_truth = vec![0; n]; - let mut in_tree = Vec::from([0]); - for i in 1..n { - let parent_idx = rng.gen_range(0..in_tree.len()); - let parent = in_tree[parent_idx]; - edges.push((i, parent)); - - ground_truth[i] = if weights[i] > weights[ground_truth[parent]] { - i - } else { - ground_truth[parent] - }; - in_tree.push(i); - } - - (edges, weights, ground_truth) - } - - #[test] - pub fn findmax_random() { - let n = 100; - let seed = rand::thread_rng().gen(); - let (edges, weights, ground_truth) = create_random_tree(n, seed); - let mut lctree = super::LinkCutTree::new(n); - for i in 0..n { - lctree.forest[i].weight = weights[i]; - } - - for (v, w) in edges { - lctree.link(v, w); - } - - for _ in 0..n * 100 { - let v = rand::thread_rng().gen_range(0..n); - assert_eq!(lctree.findmax(v), ground_truth[v]); - } - } } diff --git a/src/node.rs b/src/node.rs index 6b3585c..f9eb7e4 100644 --- a/src/node.rs +++ b/src/node.rs @@ -36,8 +36,8 @@ impl Node { Parent::Root => "Root".to_string(), }; format!( - "Node {{ idx: {}, left: {:?}, right: {:?}, parent: {:?}, max_weight_idx: {} }}", - self.idx, self.left, self.right, parent, self.max_weight_idx + "Node {{ idx: {}, left: {:?}, right: {:?}, parent: {parent:?}, max_weight_idx: {} }}", + self.idx, self.left, self.right, self.max_weight_idx ) } } diff --git a/tests/test_findmax_random.rs b/tests/test_findmax_random.rs new file mode 100644 index 0000000..efeab71 --- /dev/null +++ b/tests/test_findmax_random.rs @@ -0,0 +1,47 @@ +use lctree::LinkCutTree; +use rand::{seq::SliceRandom, Rng, SeedableRng}; + +fn create_random_tree(n: usize, seed: u64) -> (Vec<(usize, usize)>, Vec, Vec) { + let mut rng = rand::rngs::StdRng::seed_from_u64(seed); + + let mut edges = Vec::new(); + let mut weights: Vec = (0..n).map(|i| i as f64).collect(); + weights.shuffle(&mut rng); + + let mut max_to_root = vec![0; n]; + let mut in_tree = Vec::from([0]); + for i in 1..n { + let parent_idx = rng.gen_range(0..in_tree.len()); + let parent = in_tree[parent_idx]; + edges.push((i, parent)); + + max_to_root[i] = if weights[i] > weights[max_to_root[parent]] { + i + } else { + max_to_root[parent] + }; + in_tree.push(i); + } + + (edges, weights, max_to_root) +} + +#[test] +pub fn findmax_random() { + let n = 100; + let seed = rand::thread_rng().gen(); + let (edges, weights, max_to_root) = create_random_tree(n, seed); + let mut lctree = LinkCutTree::new(n); + for i in 0..n { + lctree.set_weight(i, weights[i]); + } + + for (v, w) in edges { + lctree.link(v, w); + } + + for _ in 0..n * 100 { + let v = rand::thread_rng().gen_range(0..n); + assert_eq!(lctree.findmax(v), max_to_root[v]); + } +} From eac364184de36d73f987294ee3da7c8625dfcfb0 Mon Sep 17 00:00:00 2001 From: Aziz Kayumov Date: Wed, 4 Oct 2023 11:16:29 +0900 Subject: [PATCH 2/2] update test --- src/lib.rs | 67 ++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a74cd1e..8e2a384 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -396,51 +396,48 @@ mod tests { #[test] pub fn findmax() { - let mut lctree = super::LinkCutTree::new(7); - lctree.forest[0].weight = 5.0; + let mut lctree = super::LinkCutTree::new(10); + lctree.forest[0].weight = 4.0; lctree.forest[1].weight = 2.0; lctree.forest[2].weight = 6.0; lctree.forest[3].weight = 3.0; - lctree.forest[4].weight = 4.0; - lctree.forest[5].weight = 0.0; - lctree.forest[6].weight = 1.0; + lctree.forest[4].weight = 9.0; + lctree.forest[5].weight = 5.0; + lctree.forest[6].weight = 0.0; + lctree.forest[7].weight = 7.0; + lctree.forest[8].weight = 1.0; + lctree.forest[9].weight = 8.0; // we form the following structure: - // 0(5) - // / - // 1(2) - // / - // 2(6) - // / - // 3(3) - // / \ - // 4(4) 6(1) - // / - // 5(0) - + // 0(4) + // / \ + // 1(2) 5(5) + // / \ \ + // 2(6) 3(3) 6(0) + // / \ + // 4(9) 7(7) + // / \ + // 8(1) 9(8) lctree.link(1, 0); lctree.link(2, 1); - lctree.link(3, 2); - lctree.link(4, 3); - lctree.link(5, 4); - lctree.link(6, 3); + lctree.link(3, 1); + lctree.link(4, 2); + lctree.link(5, 0); + lctree.link(6, 5); + lctree.link(7, 6); + lctree.link(8, 7); + lctree.link(9, 7); - assert_eq!(lctree.findmax(2), 2); - assert_eq!(lctree.findmax(6), 2); + // we check the node index with max weight in the path from each node to the root: assert_eq!(lctree.findmax(0), 0); - assert_eq!(lctree.findmax(5), 2); - assert_eq!(lctree.findmax(3), 2); + assert_eq!(lctree.findmax(5), 5); assert_eq!(lctree.findmax(1), 0); - assert_eq!(lctree.findmax(4), 2); - - // we cut node 3 from its parent 2: - lctree.cut(3); - assert_eq!(lctree.findmax(5), 4); - assert_eq!(lctree.findmax(6), 3); - assert_eq!(lctree.findmax(4), 4); - assert_eq!(lctree.findmax(3), 3); + assert_eq!(lctree.findmax(8), 7); assert_eq!(lctree.findmax(2), 2); - assert_eq!(lctree.findmax(1), 0); - assert_eq!(lctree.findmax(0), 0); + assert_eq!(lctree.findmax(4), 4); + assert_eq!(lctree.findmax(7), 7); + assert_eq!(lctree.findmax(9), 9); + assert_eq!(lctree.findmax(3), 0); + assert_eq!(lctree.findmax(6), 5); } }