void SubtreeUpdateMeasure(GenericTree& twd, int& centroid, int& centroid_weight, const int& current_vertex, const int& from_vertex, const int& total_size, int level, const vector<set<int> >& nodedirectory){ TreeEdgeList::iterator iter_from; int branch_total_size_other_than_from=0; int max_branch=0; for(TreeEdgeList::iterator tit=twd.get_neighbors(current_vertex).begin(); tit!=twd.get_neighbors(current_vertex).end(); tit++){ if(tit->nodeID!=from_vertex && twd[tit->nodeID].active==true){ SubtreeUpdateMeasure(twd, centroid, centroid_weight, tit->nodeID, current_vertex, total_size, level, nodedirectory); max_branch=(max_branch>tit->subtree_size)? max_branch:tit->subtree_size; branch_total_size_other_than_from+=tit->subtree_size; } else if (tit->nodeID==from_vertex)//This condition test cannot be missed, otherwise results in an logic error. iter_from=tit; } if (from_vertex>=0){ iter_from->subtree_size=total_size-branch_total_size_other_than_from-1; max_branch=(max_branch>iter_from->subtree_size)? max_branch:iter_from->subtree_size; } if(max_branch<=total_size/2){//use the centroid with smallest bag for tie break; if(int(nodedirectory[current_vertex].size())<centroid_weight){ centroid=current_vertex; centroid_weight=nodedirectory[current_vertex].size(); } } }
int SubtreeMeasure(GenericTree& gt, int& centroid, int& centroid_weight, const int& current_vertex, const int& from_vertex, const int& total_size, const vector<set<int> >& nodedirectory){ TreeEdgeList::iterator iter_from; int branch_total_size_other_than_from=0; int max_branch=0; for(TreeEdgeList::iterator tit=gt.get_neighbors(current_vertex).begin(); tit!=gt.get_neighbors(current_vertex).end(); tit++){ if(tit->nodeID!=from_vertex){ tit->subtree_size=SubtreeMeasure(gt, centroid, centroid_weight, tit->nodeID, current_vertex, total_size, nodedirectory); max_branch=(max_branch>tit->subtree_size)? max_branch:tit->subtree_size; branch_total_size_other_than_from+=tit->subtree_size; } else iter_from=tit; } if (from_vertex>=0){ iter_from->subtree_size=total_size-branch_total_size_other_than_from-1; max_branch=(max_branch>iter_from->subtree_size)? max_branch:iter_from->subtree_size; } if(max_branch<=total_size/2){//use the centroid with smallest bag for tie break; if(int(nodedirectory[current_vertex].size())<centroid_weight){ centroid=current_vertex; centroid_weight=nodedirectory[current_vertex].size(); } } return branch_total_size_other_than_from+1; }
void loopdetect(GenericTree& twd){ vector<bool> visited(twd.num_nodes(), false); for(int i=0; i<twd.num_nodes(); i++){ if(visited[i]==true) continue; visited[i]=true; queue<pair<int, int> > q; q.push(pair<int, int>(-1,i));//first is father, second is current_node while(q.size()>0){ pair<int, int> father_current=q.front(); q.pop(); for(TreeEdgeList::iterator it=twd.get_neighbors(father_current.second).begin(); it!=twd.get_neighbors(father_current.second).end(); it++){ if(it->nodeID==father_current.first) continue; if(visited[it->nodeID]==true){ cout<<"Loop Detected at: "<<it->nodeID<<endl; exit(-1); } visited[it->nodeID]=true; q.push(pair<int, int>(father_current.second, it->nodeID)); } } } }
void BalancedTreeConstr(GenericTree& twd, GenericTree& btd, const int& centroid, int level, const vector<set<int> >& nodedirectory){ twd[centroid].active=false; for(TreeEdgeList::iterator tit=twd.get_neighbors(centroid).begin(); tit!=twd.get_neighbors(centroid).end(); tit++){ if(twd[tit->nodeID].active==true){ int subcentroid=-1; int subcentroid_weight=MAX_VAL; SubtreeUpdateMeasure(twd, subcentroid, subcentroid_weight, tit->nodeID, centroid, tit->subtree_size, level, nodedirectory); neighbor btd_adj_node; neighbor btd_parent; btd_adj_node.nodeID=subcentroid; btd_parent.nodeID=centroid; btd.get_neighbors(centroid).push_back(btd_adj_node); btd.get_neighbors(btd_adj_node.nodeID).push_back(btd_parent); btd[centroid].nodelevel=level; btd[subcentroid].nodelevel=level+1; BalancedTreeConstr(twd, btd, subcentroid, level+1, nodedirectory); } } }
void buildBalancedTreeDecomposition(GenericTree& twd, GenericTree& btd, const vector<set<int> >& nodedirectory){ for(int i=0; i<twd.num_nodes(); i++){ if(twd[i].visited==true) continue; //calculate the number of vertices in the connected component (BFS) twd[i].visited=true; int CC_size=1; queue<int> q; q.push(i); while(q.size()>0){ int j=q.front(); q.pop(); for(TreeEdgeList::iterator tit=twd.get_neighbors(j).begin(); tit!=twd.get_neighbors(j).end(); tit++){ if(twd[tit->nodeID].visited==true) continue; twd[tit->nodeID].visited=true; CC_size++; q.push(tit->nodeID); } } //calculate the number of vertices in the connected component done //Fill in the neighbor size info and locate the centroid int from_vertex=-1; int centroid=-1; int centroid_weight=MAX_VAL; SubtreeMeasure(twd, centroid, centroid_weight, i, from_vertex, CC_size, nodedirectory); //Fill in the neighbor size info and locate the centroid done //Iteratively build balanced decomposition tree BalancedTreeConstr(twd, btd, centroid, 0, nodedirectory); SubtreeMeasure(btd, centroid, centroid_weight, i, from_vertex, CC_size, nodedirectory); //Iteratively build balanced decomposition tree done } }
void buildBinaryTree(GenericTree& btd, BinaryTree& btree, vector<int>& virtualnode_to_realnode){ multimap<int, int> subsize_root;////The first int is subtree size, and the second is node ID. for(int current_node=0; current_node<btd.num_nodes(); current_node++){ int current_node_level=btd[current_node].nodelevel; multimap<int, int> subsize_node;//The first int is subtree size, and the second is node ID. int parent=-1; int total_size=0; for(TreeEdgeList::iterator tit=btd.get_neighbors(current_node).begin(); tit!=btd.get_neighbors(current_node).end(); tit++){ if(btd[tit->nodeID].nodelevel>current_node_level){ subsize_node.insert(pair<int, int>(tit->subtree_size, tit->nodeID)); total_size+=tit->subtree_size; }else if (btd[tit->nodeID].nodelevel==current_node_level){ cout<<"Internal logic error 1 ocurrs on binary tree construction."<<endl; }else{//implies btd[tit->nodeID].nodelevel<current_node_level if (parent==-1){ parent=tit->nodeID; }else{ cout<<"Internal logic error 2 (multiple parents) ocurrs on binary tree construction."<<endl; } } } if (parent==-1){//implies root node subsize_root.insert(pair<int, int>(total_size+1, current_node)); } btree[current_node].parent=parent; if(subsize_node.size()==1){ btree[current_node].left_child=(subsize_node.begin())->second; }else if (subsize_node.size()==2){ multimap<int, int>::iterator mit=subsize_node.begin(); btree[current_node].left_child=mit->second; mit++; btree[current_node].right_child=mit->second; }else if (subsize_node.size()>2){ while(subsize_node.size()>2){ int first_size=(subsize_node.begin())->first; int first_node=(subsize_node.begin())->second; subsize_node.erase(subsize_node.begin()); int second_size=(subsize_node.begin())->first; int second_node=(subsize_node.begin())->second; subsize_node.erase(subsize_node.begin()); int new_node_id=btree.num_nodes(); //add a virtual node btree.addNode(new_node_id); virtualnode_to_realnode.push_back(current_node); //add a virtual node done btree[new_node_id].left_child=first_node; btree[new_node_id].right_child=second_node; btree[first_node].parent=new_node_id; btree[second_node].parent=new_node_id; subsize_node.insert(pair<int, int>(first_size+second_size, new_node_id)); } multimap<int, int>::iterator mit=subsize_node.begin(); btree[current_node].left_child=mit->second; btree[mit->second].parent=current_node; mit++; btree[current_node].right_child=mit->second; btree[mit->second].parent=current_node; } } int root=-1; if(subsize_root.size()==1){ root=(subsize_root.begin())->second; }else if (subsize_root.size()>1){ while(subsize_root.size()>1){ int first_size=(subsize_root.begin())->first; int first_node=(subsize_root.begin())->second; subsize_root.erase(subsize_root.begin()); int second_size=(subsize_root.begin())->first; int second_node=(subsize_root.begin())->second; subsize_root.erase(subsize_root.begin()); int new_node_id=btree.num_nodes(); //add a virtual node btree.addNode(new_node_id); virtualnode_to_realnode.push_back(-1);//If the root node is a virtual node, there is no real node can be associated with it. //add a virtual node done btree[new_node_id].left_child=first_node; btree[new_node_id].right_child=second_node; btree[first_node].parent=new_node_id; btree[second_node].parent=new_node_id; subsize_root.insert(pair<int, int>(first_size+second_size, new_node_id)); root=new_node_id; } } if(root<0){ cout<<"The btree is empty. Please check input."<<endl; return; }else{ btree.access_root()=root; btree[root].level=0; int maximum_level=0; queue<int> q; q.push(root); while(q.size()>0){ int j=q.front(); q.pop(); maximum_level=maximum_level>btree[j].level?maximum_level:btree[j].level; if (btree[j].left_child>=0){ btree[btree[j].left_child].level=btree[j].level+1; q.push(btree[j].left_child); } if (btree[j].right_child>=0){ btree[btree[j].right_child].level=btree[j].level+1; q.push(btree[j].right_child); } } btree.access_height()=maximum_level; } }