Exemplo n.º 1
0
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;
}