⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdiam.c

📁 任意给定三维空间的点集
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    double   directDiameter( const GFSPTree  & tree,                             GPointPair  & diam,                             const gdiam_point  dir ) const {        return  tree.brute_diameter( left->ptr_pnt_left(),                                     left->ptr_pnt_right(),                                      right->ptr_pnt_left(),                                     right->ptr_pnt_right(),                                     diam, dir );    }    double  maxDiam()  const {        return  max_diam;    }    double  minAprxDiam()  const {        double   sub_diam;                sub_diam = left->maxDiam() + right->maxDiam();        if  ( sub_diam > (max_diam / 10.0) )            return  max_diam;        return  max_diam - sub_diam / 2.0;    }};class g_heap_pairs_p;#define  UDM_SIMPLE      1#define  UDM_BIG_SAMPLE  2 class  GTreeDiamAlg{private:    GFSPTree  tree;    //double  diam;    GPointPair   pair_diam;    int  points_num;    int  threshold_brute;    int  update_diam_mode;public:    GTreeDiamAlg( gdiam_point  * arr, int  size, int  mode ) {        tree.init( arr, size );        //diam = 0;        pair_diam.init( arr[ 0 ] );        points_num = size;        threshold_brute = 40;        update_diam_mode = mode;    }    void  term() {        tree.term();    }        int  size() const {        return  points_num;    }    const GPointPair  & getDiameter() const {        return  pair_diam;    }    int  nodes_number() const {        return  tree.nodes_number();     }    void  addPairHeap( g_heap_pairs_p  & heap,                       GFSPTreeNode  * left,                       GFSPTreeNode  * right );    void  addPairHeap( g_heap_pairs_p  & heap,                       GFSPTreeNode  * left,                       GFSPTreeNode  * right,                       gdiam_point  proj,                       GFSPPair  & father );    void  split_pair( GFSPPair  & pair,                      g_heap_pairs_p  & heap, double  eps );    void  split_pair_proj( GFSPPair  & pair,                           g_heap_pairs_p  & heap, double  eps,                           gdiam_point  proj );    void  compute_by_heap( double  eps );    void  compute_by_heap_proj( double  eps, gdiam_point  proj );     double  diameter() {        return  pair_diam.distance;    }};/*--- Heap implementation ---*/typedef  int   ( *ptrCompareFunc )( void  * aPtr, void  * bPtr );typedef  void  * voidPtr_t;struct  heap_t{    voidPtr_t  * pArr;    int  curr_size, max_size;       ptrCompareFunc  pCompFunc;};void  heap_init( heap_t  * pHeap, ptrCompareFunc  _pCompFunc ){    assert( pHeap != NULL );    assert( _pCompFunc != NULL );        memset( pHeap, 0, sizeof( heap_t ) );    pHeap->pCompFunc = _pCompFunc;    pHeap->max_size = 100;    pHeap->pArr = (voidPtr_t *)malloc( sizeof( void * )                                        * pHeap->max_size );    assert( pHeap->pArr != NULL );    pHeap->curr_size = 0;}static void  resize( heap_t  * pHeap, int  size ) {    int  max_sz;    voidPtr_t  * pTmp;    if   ( size <= pHeap->max_size )         return;    max_sz = size * 2;    pTmp = (voidPtr_t *)malloc( max_sz * sizeof( void * ) );    assert( pTmp != NULL );    memset( pTmp, 0, max_sz * sizeof( void * ) );    memcpy( pTmp, pHeap->pArr, pHeap->curr_size * sizeof( void * ) );    free( pHeap->pArr );    pHeap->pArr = pTmp;}void  heap_term( heap_t  * pHeap ){    assert( pHeap != NULL );    if  ( pHeap->pArr != NULL )         free( pHeap->pArr );    memset( pHeap, 0, sizeof( heap_t ) );}void  heap_insert( heap_t  * pHeap, void  * pData ){    int  ind, father;    voidPtr_t  pTmp;    resize( pHeap, pHeap->curr_size + 1 );        ind = pHeap->curr_size;    pHeap->curr_size++;    pHeap->pArr[ ind ] = pData;    while  ( ind > 0 ) {        father = ( ind - 1 ) / 2;                if  ( (*pHeap->pCompFunc)( pHeap->pArr[ ind ],                                    pHeap->pArr[ father ] ) <= 0 )            break;        pTmp = pHeap->pArr[ ind ];        pHeap->pArr[ ind ] = pHeap->pArr[ father ];        pHeap->pArr[ father ] = pTmp;        ind = father;    }    }void  * heap_top( heap_t  * pHeap ) {    return  pHeap->pArr[ 0 ];}void  * heap_delete_max( heap_t  * pHeap ){    void  * res;    void  * pTmp;    int  ind, left, right, max_ind;    if  ( pHeap->curr_size <= 0 )        return  NULL;    res = pHeap->pArr[ 0 ];    //printf( "pHeap->curr_size: %d\n", pHeap->curr_size );    //printf( "res= %p\n", res );    pHeap->curr_size--;    pHeap->pArr[ 0 ] = pHeap->pArr[ pHeap->curr_size ];     pHeap->pArr[ pHeap->curr_size ] = NULL;    ind = 0;    while  ( ind < pHeap->curr_size ) {        left = 2 * ind + 1;        right = 2 * ind + 2;        if  ( left >= pHeap->curr_size )             break;        if  ( right >= pHeap->curr_size )             right = left;                if  ( (*pHeap->pCompFunc)( pHeap->pArr[ left ],                                    pHeap->pArr[ right ] ) <= 0 )            max_ind = right;        else            max_ind = left;        if  ( (*pHeap->pCompFunc)( pHeap->pArr[ ind  ],                                    pHeap->pArr[ max_ind ] ) >= 0 )            break;                pTmp = pHeap->pArr[ ind ];        pHeap->pArr[ ind ] = pHeap->pArr[ max_ind ];        pHeap->pArr[ max_ind ] = pTmp;        ind = max_ind;    }    return  res;}bool  heap_is_empty( heap_t  * pHeap ){    assert( pHeap != NULL );    return( pHeap->curr_size <= 0 );}int   compare_pairs( void  * _a, void  * _b ){    const GFSPPair  & a( *(GFSPPair *)_a );    const GFSPPair  & b( *(GFSPPair *)_b );    if  ( a.maxDiam() < b.maxDiam() )        return  -1;    if  ( a.maxDiam() > b.maxDiam() )        return  1;    return  0;}class  g_heap_pairs_p{private:    heap_t  heap;public:    g_heap_pairs_p() {        heap_init( &heap, compare_pairs );    }    ~g_heap_pairs_p() {        while  ( size() > 0 ) {            pop();        }        heap_term( &heap );    }    void  push( GFSPPair  & pair )     {        //printf( "pushing: (%p, %p)\n", pair.get_left(),        //        pair.get_right() );        GFSPPair  * p_pair = new GFSPPair( pair );        heap_insert( &heap, (void *)p_pair );    }    int  size() const {         return  heap.curr_size;    }    GFSPPair  top() {        return  *(GFSPPair *)heap_top( &heap );    }    void  pop() {        GFSPPair  * ptr = (GFSPPair *)heap_delete_max( &heap );        delete  ptr;    }};/* heap.implementation end */void  computeExtremePair( const gdiam_point  * arr, int  size,                          int  dim, GPointPair  & pp ){    pp.init( arr[ 0 ] );    for  ( int  ind = 1; ind < size; ind++ ) {        const gdiam_point  pnt( arr[ ind ] );        if  ( pnt[ dim ] < pp.p[ dim ] )            pp.p = pnt;        if  ( pnt[ dim ] > pp.q[ dim ] )            pp.q = pnt;    }    pp.distance = pnt_distance( pp.p, pp.q );}void  GTreeDiamAlg::compute_by_heap( double  eps ) {    g_heap_pairs_p  heap;    int  heap_limit, heap_delta;        heap_limit = HEAP_LIMIT;    heap_delta = HEAP_DELTA;        GFSPTreeNode  * root = tree.getRoot();        computeExtremePair( tree.getPoints(), points_num,                        root->getBBox().getLongestDim(),                        pair_diam );        GFSPPair  root_pair;        root_pair.init( root, root );        heap.push( root_pair );    //queue_a.pushx( root_pair );        int  count =0;    while  ( heap.size() > 0 ) {        //printf( "heap.size: %d\n", heap.size() );        //printf( "%d: curr_diam: %g\n", count++, pair_diam.distance );        GFSPPair  pair = heap.top();        heap.pop();        split_pair( pair, heap, eps );        //if  ( ( count & 0x3ff ) == 0 ) {        //    printf( "heap.size: %d\n", heap.size() );        //}        if  ( ( count & 0x3ff ) == 0 ) {            if  ( ((int)heap.size()) > heap_limit ) {                threshold_brute *= 2;                printf( "threshold_brute: %d\n", threshold_brute );                heap_limit += heap_delta;            }         }        count++;    }}void  GTreeDiamAlg::compute_by_heap_proj( double  eps,                                          gdiam_point  proj ) {    g_heap_pairs_p  heap;    int  heap_limit, heap_delta;    GPointPair   pair_diam_x;        //pnt_dump( proj );    //printf( "length = %g\n", pnt_length( proj ) );    heap_limit = HEAP_LIMIT;    heap_delta = HEAP_DELTA;        GFSPTreeNode  * root = tree.getRoot();        computeExtremePair( tree.getPoints(), points_num,                        root->getBBox().getLongestDim(),                        pair_diam_x );    pair_diam.init( pair_diam_x.p, pair_diam_x.q, proj );    GFSPPair  root_pair;        root_pair.init( root, root, proj, 0 );        //printf( "root pair distance: %g\n", root_pair.maxDiam() );    heap.push( root_pair );    //queue_a.pushx( root_pair );        int  count =0;    while  ( heap.size() > 0 ) {        //printf( "heap.size: %d\n", heap.size() );        //printf( "%d: curr_diam: %g\n", count++, pair_diam.distance );        GFSPPair  pair = heap.top();        heap.pop();        //printf( "pair distance: %g\n", pair.maxDiam() );        split_pair_proj( pair, heap, eps, proj );        //if  ( ( count & 0x3ff ) == 0 ) {        //    printf( "heap.size: %d\n", heap.size() );        //}        if  ( ( count & 0x3ff ) == 0 ) {            if  ( ((int)heap.size()) > heap_limit ) {                threshold_brute *= 2;                printf( "threshold_brute: %d\n", threshold_brute );                heap_limit += heap_delta;            }         }        count++;        //printf( "Poping!\n" );    }}void  GTreeDiamAlg::addPairHeap( g_heap_pairs_p  & heap,                                 GFSPTreeNode  * left,                                 GFSPTreeNode  * right ){    if  ( update_diam_mode == UDM_SIMPLE ) {        const gdiam_point  p( *(left->ptr_pnt_left()) );        const gdiam_point  q( *(right->ptr_pnt_left()) );                pair_diam.update_diam( p, q );    } else        if  ( update_diam_mode == UDM_BIG_SAMPLE ) {            if  ( ( left->size() < 100 )  ||  ( right->size() < 100 ) ) {                const gdiam_point  p( *(left->ptr_pnt_left()) );                const gdiam_point  q( *(right->ptr_pnt_left()) );                                pair_diam.update_diam( p, q );                } else            {                #define  UMD_SIZE        5                gdiam_point  arr_left[ UMD_SIZE ],                     arr_right[ UMD_SIZE ];                for  ( int  ind = 0; ind < UMD_SIZE; ind++ ) {                                    const gdiam_point  p( *(left->ptr_pnt_rand()) );                    const gdiam_point  q( *(right->ptr_pnt_rand()) );                    arr_left[ ind ] = p;                    arr_right[ ind ] = q;                    //pair_diam.update_diam( p, q );                }                for  ( int  ind = 0; ind < UMD_SIZE; ind++ )                    for  ( int  jnd = 0; jnd < UMD_SIZE; jnd++ )                        pair_diam.update_diam( arr_left[ ind ],                                                arr_right[ jnd ] );            }        } else {            assert( false );        }    //printf( "old_diam; %g\n", diam );    //diam = max( diam, pnt_distance( p, q ) );    //printf( "new_diam; %g\n", diam );        GFSPPair  pair;        pair.init( left, right );    if  ( pair.maxDiam() <= pair_diam.distance )        return;    heap.push( pair );}void  GTreeDiamAlg::addPairHeap( g_heap_pairs_p  & heap,                                 GFSPTreeNode  * left,                                 GFSPTreeNode  * right,                                 gdiam_point  proj,                                 GFSPPair  & father ){    const gdiam_point  p( *(left->ptr_pnt_left()) );    const gdiam_point  q( *(right->ptr_pnt_left()) );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -