void SegmentTree::constructTree(const vector<int> &array) { int height=(int)ceil(log2(array.size())); int size=2*(int)pow(2, height)-1; nodes.clear(); for(int temp=0; temp<size; temp++) nodes.push_back(SegmentTreeNode(0, 0, 0)); constructTreeHelper(array, 0, array.size()-1, 0); }
int main(int argc, char* argv[]) { /* mySF gg; test(&myF); test(gg); */ PolygonList plygnList; PolygonParser plygnPrsr("polygon.txt"); if (plygnPrsr.init()) { Polygon tmpPlygn; DataTrans tmp(tmpPlygn); while (plygnPrsr.hasNext()) { //tmpPlygn.clear(); tmp.getData().clear(); plygnPrsr.getPointVec(tmp,tmp); plygnList.push_back(tmp.getData()); } } VerSegCntnr tmpCntnr; STD::vector<VerSegCntnr> segInfoVec; GraphLib::IdType invalidId(STD::numeric_limits<int>::max()); PolygonLinkRec linkRec; LinkRecList linkRecList; size_t verSegCnt = 0; size_t totalVerSegCnt = 0; for (STD::list<Polygon>::iterator it=plygnList.begin(); it != plygnList.end(); ++it ) { assert(0 == (*it).size() % 1 && 4 <= (*it).size() ); if (!(0==(*it).size() %1 && 4<= (*it).size()) ) continue; linkRecList.push_back( STD::make_pair(&(*it), invalidId) ); verSegCnt = (*it).size() >> 2; totalVerSegCnt += verSegCnt; tmpCntnr.linkRecPtr_ = &(linkRecList.back()); //assume the first point is the most lowerleft point //O(n) complexity //the trap is: itA+=2 could be an action of 2,not as simple as adding. Polygon::const_iterator itA = (*it).begin()+1; Polygon::const_iterator itB = itA+1; for (;itA != (*it).end() && itB != (*it).end(); itA+=2,itB+=2) { tmpCntnr.seg_.head_ = ((*itA).y_<=(*itB).y_) ? (*itA) : (*itB); tmpCntnr.seg_.tail_ = ((*itA).y_<=(*itB).y_) ? (*itB) : (*itA); printf("PUSH (%d,%d)-(%d,%d)\n", tmpCntnr.seg_.head_.x_,tmpCntnr.seg_.head_.y_,tmpCntnr.seg_.tail_.x_,tmpCntnr.seg_.tail_.y_); segInfoVec.push_back(tmpCntnr); } itB = (*it).begin(); tmpCntnr.seg_.head_ = ((*itA).y_<=(*itB).y_) ? (*itA) : (*itB); tmpCntnr.seg_.tail_ = ((*itA).y_<=(*itB).y_) ? (*itB) : (*itA); printf("PUSH (%d,%d)-(%d,%d)\n", tmpCntnr.seg_.head_.x_,tmpCntnr.seg_.head_.y_,tmpCntnr.seg_.tail_.x_,tmpCntnr.seg_.tail_.y_); segInfoVec.push_back(tmpCntnr); } //sort reversely STD::sort(segInfoVec.begin(), segInfoVec.end(),sortVerSegByRevX); StNodePtrVec treeNodePtrVec(2,static_cast<StNodePtrVec::value_type>(NULL)); //Collector collector(treeNodePtrVec); SegmentTree st; CnstrntGraph graph; PolygonLinkRec *leftRecPtr = NULL, *rightRecPtr = NULL, *middleRecPtr = NULL; for(size_t idx = 0; idx < segInfoVec.size(); ++idx ) { //collect overlapped datas treeNodePtrVec.clear(); Collector collector(treeNodePtrVec,segInfoVec[idx].linkRecPtr_,segInfoVec[idx].seg_.head_.x_); st.getOverlap(segInfoVec[idx].seg_.head_.y_,segInfoVec[idx].seg_.tail_.y_, collector); //use the collected datas to build contraints if ( treeNodePtrVec[0] || treeNodePtrVec[1] ) { middleRecPtr = segInfoVec[idx].linkRecPtr_; if (invalidId == middleRecPtr->second ) middleRecPtr->second = graph.addNode(Gnode(middleRecPtr)); printf("Ref:%d %d %d \n", segInfoVec[idx].seg_.head_.y_, segInfoVec[idx].seg_.tail_.y_,segInfoVec[idx].seg_.tail_.x_); if (treeNodePtrVec[0]) { printf("left:%d,%d,%d\n", treeNodePtrVec[0]->getStartCoord(), treeNodePtrVec[0]->getEndCoord(), treeNodePtrVec[0]->getRefCoord()); leftRecPtr = static_cast<PolygonLinkRec*>(treeNodePtrVec[0]->getId()); if ( invalidId == leftRecPtr->second ) leftRecPtr->second = graph.addNode(Gnode(leftRecPtr)); SegCoord diff = segInfoVec[idx].seg_.head_.x_ - treeNodePtrVec[idx]->getRefCoord(); GraphLib::IdType edgeId; //My personal constraint: only one constraint if (graph.beginNodeIter(leftRecPtr->second) == graph.endNodeIter(leftRecPtr->second)) edgeId = graph.addEdge(leftRecPtr->second, middleRecPtr->second, diff); else edgeId = graph.getEdgeId(leftRecPtr->second,middleRecPtr->second); if (graph.getEdgeData(edgeId).userData_ > diff) { graph.getEdgeData(edgeId).userData_ = diff; } } if (treeNodePtrVec[1]) { printf("right:%d,%d,%d\n", treeNodePtrVec[1]->getStartCoord(), treeNodePtrVec[1]->getEndCoord(), treeNodePtrVec[1]->getRefCoord()); rightRecPtr = static_cast<PolygonLinkRec*>(treeNodePtrVec[1]->getId()); if ( invalidId == rightRecPtr->second ) rightRecPtr->second = graph.addNode(Gnode(rightRecPtr)); SegCoord diff = treeNodePtrVec[1]->getRefCoord() - segInfoVec[idx].seg_.head_.x_; printf("diff:%d\n",diff); GraphLib::IdType edgeId; //My personal constraint: only one edge if (graph.beginNodeIter(middleRecPtr->second) == graph.endNodeIter(middleRecPtr->second)) edgeId = graph.addEdge(middleRecPtr->second, rightRecPtr->second, diff); else edgeId = graph.getEdgeId(middleRecPtr->second, rightRecPtr->second); if (graph.getEdgeData(edgeId).userData_ > diff) { graph.getEdgeData(edgeId).userData_ = diff; graph.getEdgeData(edgeId).toId_ = rightRecPtr->second; } } } st.insert_equal( SegmentTreeNode(segInfoVec[idx].seg_.head_.y_, segInfoVec[idx].seg_.tail_.y_, segInfoVec[idx].seg_.head_.x_, (void*)(segInfoVec[idx].linkRecPtr_))); treeNodePtrVec.assign(2,static_cast<StNodePtrVec::value_type>(NULL)); } printf("NodeCount:%d EdgeCount:%d\n", graph.nodeCount(),graph.edgeCount()); CnstrntGraph::EdgeIdGen edgeIdGenObj(graph); while(edgeIdGenObj.hasNext()) { CnstrntGraph::EdgeType& edge = graph.getEdgeData(edgeIdGenObj.getNext()); CnstrntGraph::NodeType& from = graph.getNodeData(edge.fromId_); CnstrntGraph::NodeType& to = graph.getNodeData(edge.toId_); printf("edge Value:%d shape1:size:%d x:%d, shape2:size:%d x:%d\n", edge.userData_, ((Polygon*)(from.userData_.getLinkRecPtr()->first))->size(), ((Polygon*)(from.userData_.getLinkRecPtr()->first))->front().x_, ((Polygon*)(to.userData_.getLinkRecPtr()->first))->size(), ((Polygon*)(to.userData_.getLinkRecPtr()->first))->front().x_ ); } #if 0 // this code snippet is testing that if all the posotion of polygons are all // altered after the constraint grah is built, this solving system can get // all the polygons back to where it is such that the constraints are // satisfied. int shift = 10; for (PolygonList::iterator iter = ++plygnList.begin(); iter != plygnList.end(); ++iter) { for ( Polygon::iterator iter2 = (*iter).begin(); iter2 != (*iter).end(); ++iter2) { (*iter2).x_ = (*iter2).x_ + shift; (*iter2).y_ = (*iter2).y_ + shift; } shift+=10; } #endif //add a fake source GraphLib::IdType source = graph.addNode(Gnode(NULL)); graph.addEdge(source, linkRecList.front().second, 0); //longest path edgeIdGenObj.init(); int dist[ graph.nodeCount() ]; memset(dist,-1,sizeof(dist)); int parent[graph.nodeCount()]; dist[source] = 0; parent[source] = source; for (int count = 0; count < graph.nodeCount(); ++count ) { while (edgeIdGenObj.hasNext()) { CnstrntGraph::EdgeType& edge = graph.getEdgeData(edgeIdGenObj.getNext()); if ( dist[edge.toId_] < dist[edge.fromId_] + edge.userData_ ) { dist[edge.toId_] = dist[edge.fromId_] + edge.userData_; parent[edge.toId_] = edge.fromId_; } } edgeIdGenObj.init(); } edgeIdGenObj.init(); while (edgeIdGenObj.hasNext()) { CnstrntGraph::EdgeType& edge = graph.getEdgeData(edgeIdGenObj.getNext()); printf("from:%d dist:%d to:%d dist:%d\n", edge.fromId_.val(), dist[edge.fromId_], edge.toId_.val(), dist[edge.toId_] ); } //for verification printf("Start printing result for verification\n"); dfsPrint(graph,source,dist); printf("End printing result for verification\n"); #if 0 for (STD::list<Polygon>::const_iterator it=plygnList.begin(); it != plygnList.end(); ++it ) { for (STD::vector<Point>::const_iterator it2=(*it).begin(); it2 != (*it).end(); ++it2 ) { printf(" (%d %d)-", (*it2).x_, (*it2).y_); } printf("\n"); } #endif return EXIT_SUCCESS; }