int buildTreeWidthDecomposition(Graph& g, GenericTree& twd, vector<set<int> >& nodedirectory){//return the max_bag_size of this decomposition set<VertexDegreePair,VertexDegreePairComp> DegreeRank;//first is degree; second is vertex id; vector<int> DegreeList(g.num_vertices(),0); int max_bag_size=-1; for(int i=0; i<g.num_vertices(); i++){ int current_degree=g.get_degree(i); DegreeRank.insert(VertexDegreePair(i, current_degree)); DegreeList[i]=current_degree; } while(DegreeRank.size()>0){ set<VertexDegreePair,VertexDegreePairComp>::iterator minDegreeVertex=DegreeRank.begin(); DegreeRank.erase(DegreeRank.begin()); int current_vertexID=minDegreeVertex->first; //build treenode nodedirectory.push_back(set<int>()); int current_nodeID=nodedirectory.size()-1; nodedirectory.back().insert(current_vertexID); for(EdgeList::iterator vit=g.get_neighbors(current_vertexID).begin(); vit<g.get_neighbors(current_vertexID).end(); vit++){ nodedirectory.back().insert(*vit); g[*vit].nodes.push_back(current_nodeID); //update on graph EdgeList::iterator iit=g.get_neighbors(current_vertexID).begin(); EdgeList::iterator jit=g.get_neighbors(*vit).begin(); EdgeList combined; while(iit<g.get_neighbors(current_vertexID).end() && jit<g.get_neighbors(*vit).end()){ //It is assumed that a vertex itself does not appear in its adjacent list and the adjacent list is in ascending order. if(*iit==*vit){ iit++; continue; }else if (*jit==current_vertexID){ jit++; continue; } if(*iit<*jit){ combined.push_back(*iit); iit++; }else if(*iit>*jit){ combined.push_back(*jit); jit++; }else{//implies *iit==*jit combined.push_back(*iit); iit++; jit++; } } if(iit<g.get_neighbors(current_vertexID).end() && jit<g.get_neighbors(*vit).end()){ cout<<"Internal Logic Error. Exit."<<endl; exit(-1); } for(; iit<g.get_neighbors(current_vertexID).end(); iit++){ if(*iit!=*vit) combined.push_back(*iit); } for(; jit<g.get_neighbors(*vit).end(); jit++){ if(*jit!=current_vertexID) combined.push_back(*jit); } g.get_neighbors(*vit)=combined; //update on graph done //update on nodes vector<int> reduced; vector<int>::iterator itern=g[*vit].nodes.begin(); vector<int>::iterator jtern=g[current_vertexID].nodes.begin(); while(itern<g[*vit].nodes.end() && jtern<g[current_vertexID].nodes.end()){ if(*itern<*jtern){ reduced.push_back(*itern); itern++; } else if (*itern>*jtern){ jtern++; } else{//implies *itern==*jtern itern++; jtern++; } } for(; itern<g[*vit].nodes.end(); itern++) reduced.push_back(*itern); g[*vit].nodes=reduced; //update on nodes done //other update set<VertexDegreePair,VertexDegreePairComp>::iterator fit=DegreeRank.find(VertexDegreePair(*vit, DegreeList[*vit])); DegreeRank.erase(fit); DegreeRank.insert(VertexDegreePair(*vit, g.get_degree(*vit))); DegreeList[*vit]=g.get_degree(*vit); //other update done } max_bag_size=int(nodedirectory.back().size())>max_bag_size? int(nodedirectory.back().size()) : max_bag_size; //build treenode done //build decomposition tree twd.addNode(twd.num_nodes()); for(vector<int>::iterator nit=g[current_vertexID].nodes.begin(); nit<g[current_vertexID].nodes.end(); nit++){ twd.addEdge(current_nodeID, *nit);//current_nodeID shall always be larger than *nit; twd.addEdge(*nit, current_nodeID); } //build decomposition tree done //clear deleted vertex g[current_vertexID].nodes.clear(); g.get_neighbors(current_vertexID).clear(); //clear deleted vertex } return max_bag_size; }