最近点对问题

来源:互联网 发布:网络教育视频如何赚钱 编辑:程序博客网 时间:2024/04/29 04:08

 

开始

划分点集为:左点集S1,右点集S2

构造点集

判断点集的点个数是否小于4

左点集S1,右点集S2

 

开始

划分点集为:左点集S1,右点集S2

构造点集

判断点集的点个数是否小于4

左点集S1,右点集S2

 

//点结构

typedef    struct Pair

{

       int           x ;

       int           y ;

} Pair ;

//最近点对结构

typedef    struct Closest_Pair

{

       Pair  pair_a ,pair_b ;

       double            distance ;

} Closest_Pair ;

//点对结构

typedef    struct Points

{

       Pair*       p_pair ;

       int           pair_nums ;//点对数目

} Points

 

//蛮力法:分别计算每一对点之间的距离,然后找距离最小的那一对

bool Brute_Force(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)

{

       for(int i=from ;i<=to ;++i)

       {

              for(int j=i+1;j<=to ;++j)

              {

                     double     next= Account_Distance_2(points.p_pair[i] ,points.p_pair[j]) ;                 if(closest_pair.distance > next )

                     {

                            closest_pair.pair_a = points.p_pair[i] ;

                            closest_pair.pair_b = points.p_pair[j] ;

                            closest_pair.distance = next ;

                     }

              }

       }           

       return      true ;

}

//分治法:遵循分治方法,利用递归求出左子集和右子集的最近点对,然后再对两子集之间点对进一步分析比较,最后求出整个点集最近点对。

void Divide_and_Conquer(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)

{

       if( (to-from+1) <4 )

       {

                     Brute_Force(points ,closest_pair ,from ,to ) ;

                     cout << "<4    " << closest_pair.distance << endl  ;

                     //system("pause") ;

       }

       else

       {

              int           mid = (from+to)/2 ;

              int           mid_value = points.p_pair[mid].x ;

 

              Divide_and_Conquer(points ,closest_pair ,from ,mid) ;

              Divide_and_Conquer(points ,closest_pair ,mid+1 ,to) ;

              Comp_CP(points ,closest_pair ,mid ,mid_value) ;             

       }

      

       return      ;

}

 

#include "Head.h"

 //---------------------------------------------------------------------------

typedef int             RedType ;

typedef    struct Pair

{

       int           x ;

       int           y ;

} Pair ;

typedef    struct Closest_Pair

{

       Pair  pair_a ,pair_b ;

       double            distance ;

} Closest_Pair ;

typedef    struct Points

{

       Pair*       p_pair ;

       int           pair_nums ;//点对数目

} Points ;

 //---------------------------------------------------------------------------

 

Points     points ;   

Closest_Pair    closest_pair ; 

//int         pair_nums ;

 //---------------------------------------------------------------------------

double            Account_Distance_2(const Pair& A ,const Pair& B )

{

 

       return             ( (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y) ) ;

}

 //---------------------------------------------------------------------------

void Print_Points(ostream& outs ,const Points& points ,const Closest_Pair&   closest_pair )

{

       outs << "/n/n/n       随机产生点对如下:/n"  ;

       for(int i=0 ;i<points.pair_nums ;++i)

       {

              outs << "   (" << points.p_pair[i].x << " , " << points.p_pair[i].y << " ) "  ;

              if((i+1)%5==0)

              {

                     outs << endl ;

              }

       }

       outs << "/n/n  由以上点对可得最近点对为: ( "

               << closest_pair.pair_a.x << " , " << closest_pair.pair_a.y << " ) ,( "

               << closest_pair.pair_b.x << " , " << closest_pair.pair_b.y << " ) " ;

       outs << "/n     该点对距离为:" << closest_pair.distance << endl ;

}

 //---------------------------------------------------------------------------

bool Brute_Force(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)

{

       for(int i=from ;i<=to ;++i)

       {

              for(int j=i+1;j<=to ;++j)

              {

                     double            next = Account_Distance_2(points.p_pair[i] ,points.p_pair[j]) ;//sqrt(  )

                     if(closest_pair.distance > next )

                     {

                            closest_pair.pair_a = points.p_pair[i] ;

                            closest_pair.pair_b = points.p_pair[j] ;

                            closest_pair.distance = next ;

                     }

              }

       }    

      

       return      true ;

}

 //--------------------------------------------------------------------------

// 对顺序表L作归并排序。

 void Merge(char sign ,Pair SR[] ,Pair TR[] ,long i ,long m ,long n)

 { // 将有序的SR[i..m]SR[m+1..n]归并为有序的TR[i..n]

   //int j,k,l;

   for(int j=m+1,k=i;i<=m&&j<=n;++k) // SR中记录由小到大地并入TR

   {    

          if(sign=='x')

          {

                 if ( SR[i].x < SR[j].x )

                            TR[k]=SR[i++];

                 else

                            TR[k]=SR[j++];

          }

          else

          {

                 if ( SR[i].y < SR[j].y )

                            TR[k]=SR[i++];

                 else

                            TR[k]=SR[j++];

          }      

   }

   if(i<=m)

   {

     for(int l=0;l<=m-i;l++)

        {

       TR[k+l]=SR[i+l]; // 将剩余的SR[i..m]复制到TR        

        }

   }

   else

   {

     for(int l=0;l<=n-j;l++)

        {

       TR[k+l]=SR[j+l]; // 将剩余的SR[j..n]复制到TR

        

        }

   }  

 }

 //---------------------------------------------------------------------------

 void MSort(char sign ,Pair SR[] ,Pair TR1[] ,long s , long t)

 { // SR[s..t]归并排序为TR1[s..t].

      

       if(s==t)

       {

              TR1[s] = SR[s];

       }

       else

       {

              //int         m ;

              int           length = t-s+1 ;//

              Pair* TR2 = new           Pair[points.pair_nums];

              long m = (s+t)/2; // SR[s..t]平分为SR[s..m]SR[m+1..t]

              MSort(sign ,SR,TR2,s,m) ; // 递归地将SR[s..m]归并为有序的TR2[s..m]

              MSort(sign ,SR,TR2,m+1,t) ; // 递归地将SR[m+1..t]归并为有序的TR2[m+1..t]

              Merge(sign ,TR2,TR1,s,m,t) ; // TR2[s..m]TR2[m+1..t]归并到TR1[s..t]

 

              delete[]    TR2 ;

       }

      

       //            cout << " Hello       " ;

      

 }

 //---------------------------------------------------------------------------

 

void Comp_CP(const Points& points ,Closest_Pair& closest_pair ,int       mid ,int mid_value)

{

       int           i , j ;

       int           distance = sqrt( closest_pair.distance ) ;

       i = mid ;

       while( i >= 0 && points.p_pair[i].x > (mid_value-distance) )

       {

              j = mid ;

              while( points.p_pair[++j].x < (mid_value+distance) && j < points.pair_nums )

              {

                     if( points.p_pair[j].y > (points.p_pair[i].y+distance) ||

                            points.p_pair[j].y < (points.p_pair[i].y-distance) )

                            //判断在y轴是否出界

                            continue ;

                     double            next = Account_Distance_2( points.p_pair[i] ,points.p_pair[j]);//sqrt( ) 

                     if(closest_pair.distance > next )

                     {

                            closest_pair.pair_a = points.p_pair[i] ;

                            closest_pair.pair_b = points.p_pair[j] ;

                            closest_pair.distance = next ;                     

                            cout << "Comp_CP:      " << closest_pair.distance << endl  ;

                     }

             

              }

              i-- ;

       }

}

 //---------------------------------------------------------------------------

void Divide_and_Conquer(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)

{

       if( (to-from+1) <4 )

       {

                     Brute_Force(points ,closest_pair ,from ,to ) ;

                     cout << "<4    " << closest_pair.distance << endl  ;

                     //system("pause") ;

       }

       else

       {

              int           mid = (from+to)/2 ;

              int           mid_value = points.p_pair[mid].x ;

 

              Divide_and_Conquer(points ,closest_pair ,from ,mid) ;

              Divide_and_Conquer(points ,closest_pair ,mid+1 ,to) ;

              Comp_CP(points ,closest_pair ,mid ,mid_value) ;             

       }

      

       return      ;

}

 //---------------------------------------------------------------------------

void main()

{

       time_t t;

    srand((unsigned) time(&t));

              char c ;

       do

       {

              system("cls") ;

 

              cout << "/n/n  请输入你要随机产生点对的对数: " ;

              cin >> points.pair_nums ;

              points.p_pair = new Pair[points.pair_nums] ;

 

              for(int i=0 ;i<points.pair_nums ;++i)

              {

                     points.p_pair[i].x= rand()%101 ;

                     points.p_pair[i].y= rand()%101 ;

              }

              //分治法求解,先排序

              MSort('x' ,points.p_pair ,points.p_pair ,0 ,points.pair_nums-1 ) ;

       /*//

                     */

              //蛮力法求解

              closest_pair.distance = 32676 ;//MAX_SIZE

              Brute_Force(points ,closest_pair ,0 ,points.pair_nums-1 ) ;

              closest_pair.distance = sqrt( closest_pair.distance ) ;

              Print_Points( cout , points ,closest_pair ) ;

 

              //分治法求解,先排序

              //MSort('x' ,points.p_pair ,points.p_pair ,0 ,points.pair_nums-1 ) ;

 

              //分治法求解        

              closest_pair.distance = 32676 ;//MAX_SIZE

              Divide_and_Conquer(points ,closest_pair ,0 ,points.pair_nums-1 ) ;

              closest_pair.distance = sqrt( closest_pair.distance ) ;

              Print_Points( cout , points ,closest_pair ) ;

 

              //MSort('x' ,points.p_pair ,points.p_pair ,0 ,points.pair_nums-1 ) ;

 

       //     Print_Points( cout , points ,closest_pair ) ;

             

              cout << "/n/n  !!!按任意键继续,Esc退出程序!!!" << endl ;

 

       }while( (c=getch())!=27 ) ;

       return      ;

}

 //---------------------------------------------------------------------------

 

  1. #include "Head.h" 
  2.  //---------------------------------------------------------------------------
  3. typedef int     RedType ;
  4. typedef struct Pair
  5. {
  6.     int     x ;
  7.     int     y ;
  8. } Pair ;
  9. typedef struct Closest_Pair
  10. {
  11.     Pair    pair_a ,pair_b ;
  12.     double      distance ;
  13. } Closest_Pair ;
  14. typedef struct Points
  15. {
  16.     Pair*   p_pair ;
  17.     int     pair_nums ;//点对数目
  18. } Points ;
  19.  //---------------------------------------------------------------------------
  20. Points  points ;    
  21. Closest_Pair    closest_pair ;  
  22. //int       pair_nums ;
  23.  //---------------------------------------------------------------------------
  24. double      Account_Distance_2(const Pair& A ,const Pair& B )
  25. {
  26.     return      ( (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y) ) ;
  27. }
  28.  //---------------------------------------------------------------------------
  29. void    Print_Points(ostream& outs ,const Points&   points ,const Closest_Pair& closest_pair )
  30. {
  31.     outs << "/n/n/n 随机产生点对如下:/n"  ;
  32.     for(int i=0 ;i<points.pair_nums ;++i)
  33.     {
  34.         outs << "   (" << points.p_pair[i].x << " , " << points.p_pair[i].y << " ) "  ;
  35.         if((i+1)%5==0)
  36.         {
  37.             outs << endl ;
  38.         }
  39.     }
  40.     outs << "/n/n   由以上点对可得最近点对为: ( " 
  41.          << closest_pair.pair_a.x << " , " << closest_pair.pair_a.y << " ) ,( " 
  42.          << closest_pair.pair_b.x << " , " << closest_pair.pair_b.y << " ) " ;
  43.     outs << "/n 该点对距离为:" << closest_pair.distance << endl ;
  44. }
  45.  //---------------------------------------------------------------------------
  46. bool    Brute_Force(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)
  47. {
  48.     for(int i=from ;i<=to ;++i)
  49.     {
  50.         for(int j=i+1;j<=to ;++j)
  51.         {
  52.             double      next = Account_Distance_2(points.p_pair[i] ,points.p_pair[j]) ;//sqrt(  )
  53.             if(closest_pair.distance > next )
  54.             {
  55.                 closest_pair.pair_a = points.p_pair[i] ;
  56.                 closest_pair.pair_b = points.p_pair[j] ;
  57.                 closest_pair.distance = next ;
  58.             }
  59.         }
  60.     }   
  61.     
  62.     return  true ;
  63. }
  64.  //--------------------------------------------------------------------------
  65. // 对顺序表L作归并排序。
  66.  void Merge(char sign ,Pair SR[] ,Pair TR[] ,long i ,long m ,long n)
  67.  { // 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] 
  68.    //int j,k,l;
  69.    for(int j=m+1,k=i;i<=m&&j<=n;++k) // 将SR中记录由小到大地并入TR
  70.    {     
  71.        if(sign=='x')
  72.        {
  73.            if ( SR[i].x < SR[j].x )
  74.                 TR[k]=SR[i++];
  75.            else
  76.                 TR[k]=SR[j++];
  77.        }
  78.        else
  79.        {
  80.            if ( SR[i].y < SR[j].y )
  81.                 TR[k]=SR[i++];
  82.            else
  83.                 TR[k]=SR[j++];
  84.        }     
  85.    }
  86.    if(i<=m)
  87.    {
  88.      for(int l=0;l<=m-i;l++)
  89.      {
  90.        TR[k+l]=SR[i+l]; // 将剩余的SR[i..m]复制到TR      
  91.      }
  92.    }
  93.    else
  94.    {
  95.      for(int l=0;l<=n-j;l++)
  96.      {
  97.        TR[k+l]=SR[j+l]; // 将剩余的SR[j..n]复制到TR
  98.       
  99.      }
  100.    }   
  101.  }
  102.  //---------------------------------------------------------------------------
  103.  void MSort(char sign ,Pair SR[] ,Pair TR1[] ,long s , long t)
  104.  { // 将SR[s..t]归并排序为TR1[s..t].
  105.     
  106.     if(s==t)
  107.     {
  108.         TR1[s] = SR[s];
  109.     }
  110.     else
  111.     {
  112.         //int       m ;
  113.         int     length = t-s+1 ;// 
  114.         Pair* TR2 = new     Pair[points.pair_nums];
  115.         long    m = (s+t)/2; // 将SR[s..t]平分为SR[s..m]和SR[m+1..t]
  116.         MSort(sign ,SR,TR2,s,m) ; // 递归地将SR[s..m]归并为有序的TR2[s..m]
  117.         MSort(sign ,SR,TR2,m+1,t) ; // 递归地将SR[m+1..t]归并为有序的TR2[m+1..t]
  118.         Merge(sign ,TR2,TR1,s,m,t) ; // 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t]
  119.         delete[]    TR2 ;
  120.     }
  121.     
  122.     //      cout << "   Hello   " ;
  123.     
  124.  }
  125.  //---------------------------------------------------------------------------
  126. void    Comp_CP(const Points& points ,Closest_Pair& closest_pair ,int   mid ,int mid_value)
  127. {
  128.     int     i , j ; 
  129.     int     distance = sqrt( closest_pair.distance ) ;
  130.     i = mid ;
  131.     while( i >= 0 && points.p_pair[i].x > (mid_value-distance) ) 
  132.     {
  133.         j = mid ;
  134.         while( points.p_pair[++j].x < (mid_value+distance) && j < points.pair_nums )
  135.         {
  136.             if( points.p_pair[j].y > (points.p_pair[i].y+distance) || 
  137.                 points.p_pair[j].y < (points.p_pair[i].y-distance) )
  138.                 //判断在y轴是否出界
  139.                 continue ;
  140.             double      next = Account_Distance_2( points.p_pair[i] ,points.p_pair[j]);//sqrt( )  
  141.             if(closest_pair.distance > next )
  142.             {
  143.                 closest_pair.pair_a = points.p_pair[i] ;
  144.                 closest_pair.pair_b = points.p_pair[j] ;
  145.                 closest_pair.distance = next ;              
  146.                 cout << "Comp_CP:   " << closest_pair.distance << endl  ;
  147.             }
  148.         
  149.         } 
  150.         i-- ;
  151.     } 
  152. }
  153.  //---------------------------------------------------------------------------
  154. void    Divide_and_Conquer(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)
  155. {
  156.     if( (to-from+1) <4 )
  157.     {
  158.             Brute_Force(points ,closest_pair ,from ,to ) ;
  159.             cout << "<4 " << closest_pair.distance << endl  ;
  160.             //system("pause") ;
  161.     }
  162.     else
  163.     {
  164.         int     mid = (from+to)/2 ;
  165.         int     mid_value = points.p_pair[mid].x ;
  166.         Divide_and_Conquer(points ,closest_pair ,from ,mid) ;
  167.         Divide_and_Conquer(points ,closest_pair ,mid+1 ,to) ;
  168.         Comp_CP(points ,closest_pair ,mid ,mid_value) ;     
  169.     }
  170.     
  171.     return  ;
  172. }
  173.  //---------------------------------------------------------------------------
  174. void    main()
  175. {
  176.     time_t t;
  177.     srand((unsigned) time(&t));
  178.         char c ;
  179.     do
  180.     {
  181.         system("cls") ;
  182.         cout << "/n/n   请输入你要随机产生点对的对数: " ;
  183.         cin >> points.pair_nums ;
  184.         points.p_pair = new Pair[points.pair_nums] ;
  185.         for(int i=0 ;i<points.pair_nums ;++i)
  186.         {
  187.             points.p_pair[i].x= rand()%101 ;
  188.             points.p_pair[i].y= rand()%101 ;
  189.         }
  190.         //分治法求解,先排序
  191.         MSort('x' ,points.p_pair ,points.p_pair ,0 ,points.pair_nums-1 ) ;
  192.     /*//
  193.             */
  194.         //蛮力法求解
  195.         closest_pair.distance = 32676 ;//MAX_SIZE
  196.         Brute_Force(points ,closest_pair ,0 ,points.pair_nums-1 ) ;
  197.         closest_pair.distance = sqrt( closest_pair.distance ) ;
  198.         Print_Points( cout , points ,closest_pair ) ;
  199.         //分治法求解,先排序
  200.         //MSort('x' ,points.p_pair ,points.p_pair ,0 ,points.pair_nums-1 ) ;
  201.         //分治法求解     
  202.         closest_pair.distance = 32676 ;//MAX_SIZE
  203.         Divide_and_Conquer(points ,closest_pair ,0 ,points.pair_nums-1 ) ;
  204.         closest_pair.distance = sqrt( closest_pair.distance ) ;
  205.         Print_Points( cout , points ,closest_pair ) ;
  206.         //MSort('x' ,points.p_pair ,points.p_pair ,0 ,points.pair_nums-1 ) ;
  207.     //  Print_Points( cout , points ,closest_pair ) ;
  208.         
  209.         cout << "/n/n   !!!按任意键继续,Esc退出程序!!!" << endl ;
  210.     }while( (c=getch())!=27 ) ;
  211.     return  ;
  212. }
  213.  //---------------------------------------------------------------------------
原创粉丝点击