Skip to content
Snippets Groups Projects
Commit 70e33253 authored by Jonas Seidel's avatar Jonas Seidel
Browse files

state at time of submission

parent e4e8dccc
No related branches found
No related tags found
No related merge requests found
CXXFLAGS = -O0 -g -std=c++2a -Wall -Wextra -Wpedantic
dynamic_test: dynamic_test.o tree_representative.o dynamic_node.o
$(CXX) $(CXXFLAGS) -o $@ $^
dynamic_test.o: dynamic_test.cpp dynamic_node.o
$(CXX) $(CXXFLAGS) -c $<
tree_representative.o: tree_representative.cpp dynamic_node.h
$(CXX) $(CXXFLAGS) -c $<
dynamic_node.o: dynamic_node.cpp dynamic_node.h biased_binary_node.o
$(CXX) $(CXXFLAGS) -c $<
biased_test: tree_test.o
$(CXX) $(CXXFLAGS) -o $@ $^
......@@ -13,6 +25,6 @@ biased_binary_node.o: biased_binary_node.cpp biased_binary_node.h
$(CXX) $(CXXFLAGS) -c $<
clean:
rm -f *.o biased_test
rm -f *.o *.gch biased_test dynamic_test
.PHONY: clean
Purpose
===
This was supposed to be a implementation of the _"Dynamic Tree"_ data structure described in **[1]**. Specifically using the recommended _"Biased (Binary) Tree"_ data structure described in **[2]**. Sadly this could not be accomplished in time for submission.
Supported Operations
===
At time of submission the _BiasedBinaryTree<T>_ supports splitting and joining, which are the key operations needed for an efficient implementation of the Algorithm described in **[3]**. A test of these can be compiled using **make biased_test**.
_TreeRepresentative_:_BiasedBinaryTree<DynamicAddon>_ is the type maintaining the binary tree structure described in **[1]** and is supposed to maintain _DynamicAddon_'s invariants. It is currently mostly a skeleton.
_DynamicAddon_ is the Type providing most of the functionality. Its implementation, too, is incomplete.
Plans
===
If changes will be made they will go to a different branch, meaning the current state will be archived for evaluation. It seems unlikely that any pushes will be made during the exam period.
---
* **[1]** Daniel D. Sleator, Robert Endre Tarjan _A Data Structure for Dynamic Trees_ Journal of Computer and System Science (1983)
* **[2]** Samuel W. Bent, Daniel D. Sleator, Robert E. Tarjan _Biased Search Trees_ Society for Industrial and Applied Mathematics (1985)
* **[3]** Ravindra K. Ahuja, Dorit S. Hochbaum, James B. Orlin _Solving the Convex Cost Integer Dual Network Flow Problem_ Management Science (2003)
......@@ -177,7 +177,7 @@ std::shared_ptr<BiasedBinaryNode<T>> BiasedBinaryNode<T>::local_join(std::shared
}
template <typename T>
void BiasedBinaryNode<T>::split_at(std::shared_ptr<BiasedBinaryNode<T>> split_pos, std::shared_ptr<BiasedBinaryNode<T>>& before, std::shared_ptr<BiasedBinaryNode<T>>& after){
void BiasedBinaryNode<T>::split_at(std::shared_ptr<BiasedBinaryNode<T>> split_pos,std::shared_ptr<BiasedBinaryNode<T>>& before, std::shared_ptr<BiasedBinaryNode<T>>& after, std::shared_ptr<BiasedBinaryNode<T>>& removed_interior_parent, std::shared_ptr<BiasedBinaryNode<T>>& removed_interior_root){
#ifdef PROTOCOL
std::cout << "\033[36mSplitting\033[0m" << std::endl;
std::cout << *this;
......@@ -201,26 +201,28 @@ void BiasedBinaryNode<T>::split_at(std::shared_ptr<BiasedBinaryNode<T>> split_po
#endif
std::shared_ptr<BiasedBinaryNode<T>> parent_lock = split_pos->parent().lock();
if(parent_lock == nullptr){
removed_interior_root = this->me();
return;
}else if(split_pos->is_left_child()){
if(parent_lock->right_child() != nullptr){
after = parent_lock->right_child()->global_join(after);
after = parent_lock->right_child()->global_join(after, parent_lock);
after->parent().reset();
}
}else{
if(parent_lock->left_child() != nullptr){
before = parent_lock->left_child()->global_join(before);
before = parent_lock->left_child()->global_join(before, parent_lock);
before->parent().reset();
}
}
parent_lock->right_child().reset(); //orphan one side and disconnect the joined tree from the remaining nodes
parent_lock->left_child().reset();
split_pos.reset();
this->split_at(parent_lock, before, after);
this->split_at(parent_lock, before, after, removed_interior_parent, removed_interior_root);
removed_interior_parent = parent_lock;
}
template <typename T>
std::shared_ptr<BiasedBinaryNode<T>> BiasedBinaryNode<T>::global_join(std::shared_ptr<BiasedBinaryNode<T>> other){
std::shared_ptr<BiasedBinaryNode<T>> BiasedBinaryNode<T>::global_join(std::shared_ptr<BiasedBinaryNode<T>> other, std::shared_ptr<BiasedBinaryNode> connector_node){
#ifdef PROTOCOL
std::cout << "\033[36mJoin\033[0m" << std::endl;
std::cout << *this;
......@@ -239,7 +241,13 @@ std::shared_ptr<BiasedBinaryNode<T>> BiasedBinaryNode<T>::global_join(std::share
std::cout << "Case 1" << std::endl;
#endif
std::weak_ptr<BiasedBinaryNode<T>> old_parent = this->parent();
std::shared_ptr<BiasedBinaryNode<T>> new_common_parent = std::make_shared<BiasedBinaryNode<T>>(std::max(this->rank(), other->rank())+1);
std::shared_ptr<BiasedBinaryNode<T>> new_common_parent;
if(connector_node != nullptr){
connector_node->rank() = std::max(this->rank(), other->rank())+1;
new_common_parent = connector_node;
}else{
new_common_parent = std::make_shared<BiasedBinaryNode<T>>(std::max(this->rank(), other->rank())+1);
}
new_common_parent->rewire_left_child_with(this->me());
new_common_parent->rewire_right_child_with(other);
new_common_parent->parent() = old_parent;
......
......@@ -24,10 +24,10 @@ private:
std::weak_ptr<BiasedBinaryNode<T>> _parent;
std::shared_ptr<BiasedBinaryNode<T>> _left_child;
std::shared_ptr<BiasedBinaryNode<T>> _right_child;
std::shared_ptr<BiasedBinaryNode<T>> tilt_right();
std::shared_ptr<BiasedBinaryNode<T>> tilt_left();
std::shared_ptr<BiasedBinaryNode<T>> local_join(std::shared_ptr<BiasedBinaryNode<T>>);
protected:
virtual std::shared_ptr<BiasedBinaryNode<T>> tilt_right();
virtual std::shared_ptr<BiasedBinaryNode<T>> tilt_left();
virtual std::shared_ptr<BiasedBinaryNode<T>> local_join(std::shared_ptr<BiasedBinaryNode<T>>);
public:
BiasedBinaryNode(unsigned long);
~BiasedBinaryNode();
......@@ -43,15 +43,14 @@ public:
std::shared_ptr<BiasedBinaryNode<T>>& left_child();
std::shared_ptr<BiasedBinaryNode<T>>& right_child();
void rewire_right_child_with(std::shared_ptr<BiasedBinaryNode<T>>);
void rewire_left_child_with(std::shared_ptr<BiasedBinaryNode<T>>);
void replace_with(std::shared_ptr<BiasedBinaryNode<T>>);
virtual void rewire_right_child_with(std::shared_ptr<BiasedBinaryNode<T>>);
virtual void rewire_left_child_with(std::shared_ptr<BiasedBinaryNode<T>>);
virtual void replace_with(std::shared_ptr<BiasedBinaryNode<T>>);
void split_at(std::shared_ptr<BiasedBinaryNode<T>> split_pos,std::shared_ptr<BiasedBinaryNode<T>>& before, std::shared_ptr<BiasedBinaryNode<T>>& after);
std::shared_ptr<BiasedBinaryNode<T>> global_join(std::shared_ptr<BiasedBinaryNode<T>>);
virtual void split_at(std::shared_ptr<BiasedBinaryNode<T>> split_pos,std::shared_ptr<BiasedBinaryNode<T>>& before, std::shared_ptr<BiasedBinaryNode<T>>& after, std::shared_ptr<BiasedBinaryNode<T>>& removed_interior_parent, std::shared_ptr<BiasedBinaryNode<T>>& removed_interior_root);
virtual std::shared_ptr<BiasedBinaryNode<T>> global_join(std::shared_ptr<BiasedBinaryNode<T>>, std::shared_ptr<BiasedBinaryNode<T>> = nullptr);
};
#include "biased_binary_node.cpp"
#endif
......@@ -22,10 +22,10 @@ void BiasedBinaryTree<T>::join(BiasedBinaryTree<T> other){
}
template <typename T>
void BiasedBinaryTree<T>::split_at(std::shared_ptr<BiasedBinaryNode<T>> split_pos,BiasedBinaryTree<T>& before, BiasedBinaryTree<T>& after){
void BiasedBinaryTree<T>::split_at(std::shared_ptr<BiasedBinaryNode<T>> split_pos,BiasedBinaryTree<T>& before, BiasedBinaryTree<T>& after, std::shared_ptr<BiasedBinaryNode<T>> removed_interior_parent, std::shared_ptr<BiasedBinaryNode<T>> removed_interior_root){
std::shared_ptr<BiasedBinaryNode<T>> root_before;
std::shared_ptr<BiasedBinaryNode<T>> root_after;
this->root()->split_at(split_pos, root_before, root_after);
this->root()->split_at(split_pos, root_before, root_after, removed_interior_parent, removed_interior_root);
before = BiasedBinaryTree<T>(root_before);
after = BiasedBinaryTree<T>(root_after);
}
......
......@@ -19,7 +19,7 @@ public:
std::shared_ptr<BiasedBinaryNode<T>>& root();
void join(BiasedBinaryTree<T>);
void split_at(std::shared_ptr<BiasedBinaryNode<T>>, BiasedBinaryTree<T>&, BiasedBinaryTree<T>&);
void split_at(std::shared_ptr<BiasedBinaryNode<T>>, BiasedBinaryTree<T>&, BiasedBinaryTree<T>&, std::shared_ptr<BiasedBinaryNode<T>>, std::shared_ptr<BiasedBinaryNode<T>>);
};
#include "biased_binary_tree.cpp"
......
#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);
}
#ifndef DYNAMIC_NODE_H
#define DYNAMIC_NODE_H
#include "biased_binary_node.h"
#include <algorithm>
class DynamicNode;
/*
class overrides operator so that DynamicNode(see below) can support its invariants
*/
class TreeRepresentative : public BiasedBinaryNode<DynamicNode*>{
protected:
std::shared_ptr<BiasedBinaryNode<DynamicNode*>> tilt_right();
std::shared_ptr<BiasedBinaryNode<DynamicNode*>> tilt_left();
std::shared_ptr<BiasedBinaryNode<DynamicNode*>> local_join(std::shared_ptr<BiasedBinaryNode<DynamicNode*>>);
public:
TreeRepresentative(unsigned long);
void rewire_right_child_with(std::shared_ptr<BiasedBinaryNode<DynamicNode*>>);
void rewire_left_child_with(std::shared_ptr<BiasedBinaryNode<DynamicNode*>>);
void replace_with(std::shared_ptr<BiasedBinaryNode<DynamicNode*>>);
void split_at(std::shared_ptr<BiasedBinaryNode<DynamicNode*>> split_pos,std::shared_ptr<BiasedBinaryNode<DynamicNode*>>& before, std::shared_ptr<BiasedBinaryNode<DynamicNode*>>& after, std::shared_ptr<BiasedBinaryNode<DynamicNode*>>& removed_interior_parent, std::shared_ptr<BiasedBinaryNode<DynamicNode*>>& removed_interior_root);
std::shared_ptr<BiasedBinaryNode<DynamicNode*>> global_join(std::shared_ptr<BiasedBinaryNode<DynamicNode*>>, std::shared_ptr<BiasedBinaryNode<DynamicNode*>> = nullptr);
};
/*
Realizes Sleator and Tarjans Dynamic Tree Datastruct (using Biased Trees)
*/
class DynamicNode{
friend TreeRepresentative;
std::shared_ptr<TreeRepresentative> const _node;
bool _reversed;
double _relative_path_weight; // netcost in paper
bool _rel_path_encoded;
double _relative_structure_weight; // netmin in paper
bool _rel_struct_encoded;
void decode_rel_path_and_struct_w();
void encode_rel_path_and_struct_w();
void decode_rel_struct_w();
protected:
std::shared_ptr<TreeRepresentative> node();
bool& reversed();
public:
DynamicNode(unsigned long);
bool global_reversed();
void reverse();
double weight(); // for interior nodes
double min_path_weight(); // "
double send(double); // Pushes along the entire path to which the current node belongs
std::shared_ptr<TreeRepresentative>& head(); // implementation differes from paper
std::shared_ptr<TreeRepresentative>& tail(); // "
std::shared_ptr<TreeRepresentative>& before(); // for leaves
std::shared_ptr<TreeRepresentative>& after(); // "
private:
// other data to reflect Graph
bool is_leaf();
std::vector<DynamicNode> reachable;
};
#endif
#include "dynamic_node.h"
#include <iostream>
int main(){
DynamicNode node (5);
std::cout << node.global_reversed() << std::endl;
node.reverse();
std::cout << node.global_reversed() << std::endl;
return 0;
}
#include "dynamic_node.h"
TreeRepresentative::TreeRepresentative(unsigned long rank) : BiasedBinaryNode<DynamicNode*>(rank) {}
std::shared_ptr<BiasedBinaryNode<DynamicNode*>> TreeRepresentative::tilt_right(){
auto other = this->left_child();
if(other == nullptr) return this->me();
this->value()->decode_rel_path_and_struct_w();
other->value()->decode_rel_path_and_struct_w();
if(other->left_child() != nullptr) other->left_child()->value()->decode_rel_struct_w();
if(other->right_child() != nullptr) other->right_child()->value()->decode_rel_struct_w();
if(this->right_child() != nullptr) this->right_child()->value()->decode_rel_struct_w();
auto new_root = BiasedBinaryNode<DynamicNode*>::tilt_right();
if(this->left_child() == other){
other->value()->encode_rel_path_and_struct_w();
this->value()->encode_rel_path_and_struct_w();
}else{
this->value()->encode_rel_path_and_struct_w();
other->value()->encode_rel_path_and_struct_w();
}
return new_root;
}
std::shared_ptr<BiasedBinaryNode<DynamicNode*>> TreeRepresentative::tilt_left(){
auto other = this->right_child();
if(other == nullptr) return this->me();
this->value()->decode_rel_path_and_struct_w();
other->value()->decode_rel_path_and_struct_w();
if(other->left_child() != nullptr) other->left_child()->value()->decode_rel_struct_w();
if(other->right_child() != nullptr) other->right_child()->value()->decode_rel_struct_w();
if(this->left_child() != nullptr) this->left_child()->value()->decode_rel_struct_w();
auto new_root = BiasedBinaryNode<DynamicNode*>::tilt_right();
if(this->right_child() == other){
other->value()->encode_rel_path_and_struct_w();
this->value()->encode_rel_path_and_struct_w();
}else{
this->value()->encode_rel_path_and_struct_w();
other->value()->encode_rel_path_and_struct_w();
}
return new_root;
}
void TreeRepresentative::rewire_right_child_with(std::shared_ptr<BiasedBinaryNode<DynamicNode*>> new_child){
}
......@@ -21,7 +21,8 @@ int main(){
BiasedBinaryTree<int> after;
std::cout << "-.-.-.-" << std::endl;
std::cout << "use_count : " << split_pos.use_count() << std::endl;
start.split_at(split_pos, before, after);
std::shared_ptr<BiasedBinaryNode<int>> removed_parent, removed_root;
start.split_at(split_pos, before, after, removed_parent, removed_root);
std::cout << "----------------" << std::endl;
std::cout << before;
std::cout << "----------------" << std::endl;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment