用分治法求解最近点对问题

一、求解最近点对问题
【问题描述】给定平面S上n个点,找其中的一对点,使得在n个点组成的所有点对中,该点对间的距离最小。
(1)蛮力法求解最近点对问题

double ClosestPoints(vector<Point> a,int leftindex,int rightindex) 
{  int i,j;
   double d,mindist =INF;
   for (i=leftindex;i<=rightindex;i++)
 for (j=i+1;j<=rightindex;j++)
 {  d=Distance(a[i],a[j]);
    if (d<mindist)
     mindist=d;
 }
   return mindist;
}

在这里插入图片描述
(2)分治法求解
1) 基本思路
在这里插入图片描述
2)步骤

  1. 对a中所有点按x坐标从小到大排序,将a中点集复制到b中,对b中所有点按y坐标从小到大排序。设求出a中最近点对距离为d。
  2. 如果a中点数少于4,则采用蛮力法直接计算各点的最近距离d。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    3)算法
bool pointxcmp(Point &p1,Point &p2) 
//用于点按x坐标递增排序
{
  return p1.x<p2.x;
}
bool pointycmp(Point &p1,Point &p2)  
//用于点按y坐标递增排序
{
  return p1.y<p2.y;
}
double ClosestPoints11(vector<Point> &a,vector<Point> b,int leftindex,int rightindex)
//递归求a[leftindex..rightindex]中的最近点对
{  vector<Point> leftb,rightb,b1;
   int i,j,midindex;
   int leftminindex1,leftminindex2;  //左边的最近点对
   int rightminindex1,rightminindex2; //右边的最近点对
   double d1,d2,d3,d;
   if ((rightindex-leftindex+1)<4) 
     //少于4个点,直接用蛮力法求解
  { d=ClosestPoints(a,leftindex,rightindex);
 return d;
  }
  midindex=(leftindex+rightindex)/2;  //求中间位置
  for (i=0;i<b.size();i++)  //将b中点集分为左右两部分
 if (b[i].x<a[midindex].x)
   leftb.push_back(b[i]);
 else
   rightb.push_back(b[i]);
    d1=ClosestPoints11(a,leftb,leftindex,midindex);
    d2=ClosestPoints11(a,rightb,midindex+1,rightindex); 
    d=min(d1,d2);
  //求中间部分点对的最小距离
   for (i=0;i<b.size();i++)   //将b中间宽度为2*d的带状区域内
                   //的子集复制到b1中
      if (fabs(b[i].x-a[midindex].x)<=d)
          b1.push_back(b[i]);
   double tmpd3;
   for (i=0;i<b1.size();i++) //求b1中最近点对
      for (j=i+1;j<b1.size();j++)
      {
         if ((b1[j].y-b1[i].y)>=d) break;
         tmpd3=Distance(b1[i],b1[j]);
         if (tmpd3<d3)
     d3=tmpd3;
      }
   d=min(d,d3);
   return d;
}
 //求中间部分点对的最小距离
   for (i=0;i<b.size();i++)   //将b中间宽度为2*d的带状区域内
                   //的子集复制到b1中
      if (fabs(b[i].x-a[midindex].x)<=d)
          b1.push_back(b[i]);
   double tmpd3;
   for (i=0;i<b1.size();i++) //求b1中最近点对
      for (j=i+1;j<b1.size();j++)
      {
         if ((b1[j].y-b1[i].y)>=d) break;
         tmpd3=Distance(b1[i],b1[j]);
         if (tmpd3<d3)
     d3=tmpd3;
      }
   d=min(d,d3);
   return d;
}

4)算法分析
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 15
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值