Select Git revision
biased_binary_node.cpp
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
dynamic_node.cpp 3.01 KiB
#include "dynamic_node.h"
#include <cfloat>
void DynamicNode::decode_rel_struct_w(){
this->_relative_structure_weight = this->min_path_weight();
this->_rel_struct_encoded = false;
}
void DynamicNode::decode_rel_path_and_struct_w(){
this->decode_rel_struct_w();
this->_relative_path_weight += this->_relative_structure_weight;
this->_rel_path_encoded = false;
}
void DynamicNode::encode_rel_path_and_struct_w(){
double min = DBL_MAX;
if(this->node()->left_child() != nullptr){
min = std::min(min, this->node()->left_child()->value()->_relative_structure_weight);
}
if(this->node()->right_child() != nullptr){
min = std::min(min, this->node()->right_child()->value()->_relative_structure_weight);
}
if(min == DBL_MAX){ // the node appears to be a leave, meaning that no edge cost can possibly be represented
this->_relative_path_weight = 0;
this->_relative_structure_weight = 0;
this->_rel_path_encoded = true;
this->_rel_struct_encoded = true;
return;
}
this->_relative_structure_weight = min-this->node()->parent().lock()->value()->min_path_weight();
this->_rel_struct_encoded = true;
if(this->node()->left_child() != nullptr){
this->node()->left_child()->value()->_relative_structure_weight -= min;
this->node()->left_child()->value()->_rel_struct_encoded = true;
}
if(this->node()->right_child() != nullptr){
this->node()->right_child()->value()->_relative_structure_weight -= min;
this->node()->right_child()->value()->_rel_struct_encoded = true;
}
this->_relative_path_weight -= min;
this->_rel_path_encoded = true;
}
std::shared_ptr<TreeRepresentative> DynamicNode::node(){
return this->_node;
}
bool& DynamicNode::reversed(){
return this->_reversed;
}
DynamicNode::DynamicNode(unsigned long rank) : _node(std::make_shared<TreeRepresentative>(rank)) {
this->_reversed = false;
this->_relative_path_weight = 0;
this->_relative_structure_weight = 0;
}
bool DynamicNode::global_reversed(){
if(this->node()->parent().lock() == nullptr) return this->reversed();
int rec_val = this->node()->parent().lock()->value()->global_reversed();
return (rec_val+this->reversed()) % 2;
}
void DynamicNode::reverse(){
this->reversed() = (this->reversed() + 1) % 2;
}
double DynamicNode::weight(){
if(!this->_rel_path_encoded) return this->_relative_path_weight;
return this->_relative_path_weight+this->min_path_weight();
}
double DynamicNode::min_path_weight(){
if(!this->_rel_struct_encoded) return this->_relative_structure_weight;
auto parent_lock = this->node()->parent().lock();
if(parent_lock == nullptr) return this->_relative_structure_weight;
return this->_relative_structure_weight + parent_lock->value()->min_path_weight();
}
double DynamicNode::send(double amount){
auto parent_lock = this->node()->parent().lock();
if(parent_lock == nullptr){
double send_amount = std::min(this->_relative_structure_weight, amount);
this->_relative_structure_weight -= send_amount;
return send_amount;
}
return parent_lock->value()->send(amount);
}