This commit is contained in:
2024-09-18 15:54:59 -04:00
parent 42e04e2e0f
commit e00ae0e9ab

View File

@@ -123,6 +123,7 @@ struct RoyaltyTree {
} }
struct Royalty { struct Royalty {
count: usize, // Here and below
weight: FiNum, // Here and below weight: FiNum, // Here and below
lazy: FiNum, // To be distributed to here and to below based on weights lazy: FiNum, // To be distributed to here and to below based on weights
acc: FiNum, // Accumulated here acc: FiNum, // Accumulated here
@@ -131,7 +132,7 @@ struct Royalty {
impl Royalty { impl Royalty {
fn new() -> Self { fn new() -> Self {
Royalty { weight:FiNum::zero(), lazy:FiNum::zero(), acc:FiNum::zero(), order_id:0, } Royalty { weight:FiNum::zero(), lazy:FiNum::zero(), acc:FiNum::zero(), order_id:0, count:0 }
} }
} }
@@ -147,6 +148,9 @@ impl RoyaltyTree {
fn weight_here_below(&self, index:usize) -> FiNum { fn weight_here_below(&self, index:usize) -> FiNum {
self.tree[index].weight self.tree[index].weight
} }
fn count_here_below(&self, index:usize) -> usize {
self.tree[index].count
}
fn weight_below(&self, index: usize) -> FiNum { fn weight_below(&self, index: usize) -> FiNum {
if index&1==0 { if index&1==0 {
FiNum::zero() FiNum::zero()
@@ -156,6 +160,15 @@ impl RoyaltyTree {
w0+w1 w0+w1
} }
} }
fn count_below(&self, index: usize) -> usize {
if index&1==0 {
0
} else {
let c0=self.count_here_below(wt_left (index).unwrap());
let c1=self.count_here_below(wt_right(index).unwrap());
c0+c1
}
}
fn weight_here(&self, index:usize) -> FiNum { fn weight_here(&self, index:usize) -> FiNum {
if index&1==0 { if index&1==0 {
self.weight_here_below(index) self.weight_here_below(index)
@@ -165,6 +178,16 @@ impl RoyaltyTree {
w0-w1 w0-w1
} }
} }
fn count_here(&self, index:usize) -> usize {
if index&1==0 {
self.count_here_below(index)
} else {
let c0=self.count_here_below(index);
let c1=self.count_below(index);
if c1>c0 { println!("Count_here({}) ... c0={} c1={}",index,c0,c1) };
c0-c1
}
}
fn expand_to(&mut self, index: usize) -> &mut Self { fn expand_to(&mut self, index: usize) -> &mut Self {
for _ in self.tree.len()..=index { self.tree.push(Royalty::new()) } for _ in self.tree.len()..=index { self.tree.push(Royalty::new()) }
self self
@@ -223,6 +246,24 @@ impl RoyaltyTree {
let weight=self.weight_here(pos); let weight=self.weight_here(pos);
self.sub_weight(pos,weight); self.sub_weight(pos,weight);
} }
fn random_order_id(&self, rng: &mut rand::rngs::StdRng) -> Option<usize> {
if self.tree.len()==0 { return None }
let mut f=self.forefather();
while self.count_here_below(f)>0 {
let c0=self.count_here(f);
let c1=if f&1==0 { 0 } else { self.count_here_below(wt_left(f).unwrap()) };
let c2=if f&1==0 { 0 } else { self.count_here_below(wt_right(f).unwrap()) };
let c=c0+c1+c2;
let r=rng.gen_range(0..c);
if r<c0 { return Some(f) }
else if r<c1 { f=wt_left(f).unwrap() }
else { f=wt_right(f).unwrap() }
}
None
}
fn capture_partial(&mut self, id: usize, weight: FiNum) -> FiNum {
FiNum::zero()
}
fn sub_weight(&mut self, index: usize, weight: FiNum) { fn sub_weight(&mut self, index: usize, weight: FiNum) {
self.get_royalty(index); self.get_royalty(index);
let redist=self.tree[index].acc; let redist=self.tree[index].acc;
@@ -240,10 +281,12 @@ impl RoyaltyTree {
let mut ff0=self.forefather(); let mut ff0=self.forefather();
let ff1=wt_forefather(index); let ff1=wt_forefather(index);
let w=self.tree[ff0].weight; let w=self.tree[ff0].weight;
let c=self.tree[ff0].count;
self.expand_to(ff1*2); self.expand_to(ff1*2);
while ff0<ff1 { while ff0<ff1 {
ff0=wt_parent(ff0); ff0=wt_parent(ff0);
self.tree[ff0].weight=w; self.tree[ff0].weight=w;
self.tree[ff0].count=c;
} }
} }
else { self.expand_to(wt_forefather(index)*2); } else { self.expand_to(wt_forefather(index)*2); }
@@ -251,9 +294,11 @@ impl RoyaltyTree {
let mut index=index; let mut index=index;
let ff=self.forefather(); let ff=self.forefather();
while index!=ff { while index!=ff {
if self.tree[index].weight==FiNum::zero() && weight>FiNum::zero() { self.tree[index].count+=1; }
self.tree[index].weight+=weight; self.tree[index].weight+=weight;
index=wt_parent(index); index=wt_parent(index);
} }
if self.tree[index].weight==FiNum::zero() && weight>FiNum::zero() { self.tree[index].count+=1; }
self.tree[index].weight+=weight; self.tree[index].weight+=weight;
} }
fn forefather(&self) -> usize { fn forefather(&self) -> usize {
@@ -262,7 +307,7 @@ impl RoyaltyTree {
fn dump(&mut self) { fn dump(&mut self) {
for index in 0..self.tree.len() { for index in 0..self.tree.len() {
let roy=self.get_royalty(index); let roy=self.get_royalty(index);
println!("Index {} Weight {} Lazy {} Acc {} Royalty {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc,roy); println!("Index {} Count {} Weight {} Lazy {} Acc {} Royalty {}",index,self.tree[index].count,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc,roy);
} }
} }
fn raw_dump(&mut self) { fn raw_dump(&mut self) {
@@ -749,11 +794,16 @@ fn wt_forefather(max_index:usize) -> usize {
fn royalty_stuff() { fn royalty_stuff() {
let mut rng: StdRng=StdRng::seed_from_u64(13u64); let mut rng: StdRng=StdRng::seed_from_u64(13u64);
let mut rt=RoyaltyTree::new(); let mut rt=RoyaltyTree::new();
for i in 1..1000 { rt.add_weight(4,FiNum::new_i32(1));
rt.add_weight(5,FiNum::new_i32(1));
rt.dump();
return;
for i in 1..1000000 {
rt.dump();
match rng.gen_range(0..10) { match rng.gen_range(0..10) {
0 => rt.add_weight(rng.gen_range(0..32),FiNum::new(rng.gen_range(0..101))), 0 => rt.add_weight(rng.gen_range(0..8),FiNum::new_i32(rng.gen_range(0..101))),
1 => rt.add_royalty(FiNum::new(rng.gen_range(0..10))), 1 => rt.add_royalty(FiNum::new_i32(rng.gen_range(0..10))),
2 => rt.sub_royalty(FiNum::new(rng.gen_range(0..10))), 2 => println!("Random Order ID: {:?}",rt.random_order_id(&mut rng)),
_ => (), _ => (),
} }
} }