Пример #1
0
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;
}