算法设计--蛮力法 分治法求最近对问题(C++实现)

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

最近对问题?

设p1=(x1,y1), p2(x2,y2), ....,pn=(xn,yn)是平面上n个点构成的集合S,最近对问题就是找出集合S中距离最近的点对。

两种算法思想:

1. 蛮力法:顾名思义,利用正常的思维,使用强硬的方式求解出结果。

2. 分治法:分治,分而治之,把大问题分解为小问题,主要有三个过程:划分、求解子问题、合并。


直接上代码:

蛮力法求解最近对问题:

#include "iostream" #include "math.h" #include "time.h"#include "stdlib.h" using namespace std; struct P {   int x;   int y; }; double ClosePoints(int n,P a[],int &index1,int &index2) {      double  d;      double  Dist=10000;   for (int i=0;i-1;i++)   {     for (int j=i+1;j<=n-1;j++)     {       d=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);       if(d<=Dist)       {         Dist=d;         index1=i;         index2=j;       }     }   }  return Dist;   } void main (void) {      clock_t start,end;   int g;   int s,e;   P a[10000];   for (int i=1;i<4;i++)   {      cout<<"输入坐标的个数(10000以内)";    cin>>g;   srand(time(NULL));     for (int r=0;r-123);                a[r].y=rand()%(g-1234);     }     start=clock();     double w=ClosePoints(g,a,s,e);           end=clock();     cout<<"最近的两个点是:P1("<","<") P2("<","<")"<<endl;   cout<<"距离是:"<<sqrt(w)<<endl;           cout<<"蛮力法求最近对用时:"<<(double)(end-start)/CLOCKS_PER_SEC<<"ms"<<endl;     cout<<"============================================================="<<endl;      }  } 

分治法求解最近对问题:

#include#include "cstdio" #include "cstring" #include "math.h" #include "time.h" #include "stdlib.h" #include "algorithm"using namespace std;#define eps 1e-8#define N 10000//定义一个保存坐标的结构体struct point { double x,y;};point node[N * 2];point d[N];point c[N];point b[N];int cmp(point a, point b)  //比较两点之间的y值return a.y < b.y;}int cmp1(point a, point b)if(a.x != b.x)  return a.x < b.x; return a.y < b.y;}double min(double a, double b) //求a和b两者较小值{  return a > b? b:a;}double dx(double x1, double x2) if((x1 - x2) > eps && (x1 - x2) < eps) {  return 0; } else if(x1 > x2) {  return x1 - x2; } else if(x1 < x2) {  return x2 - x1; }}double ds(point a, point b)  //求两点之间的距离return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}/*** 最近对问题* 三种情况:* 1.在子集S1中* 2.在自己S2中* 3.最近的两个点分别在子集S1和S2中*/double closestPoints(point node[], int n)int i, j; int Dist = 99999;  //无穷大数 if(n < 2)    //只有一个点,不存在最近对  return 0int m = (n - 1) / 2//m是各个坐标的中位数 for(i = m + 1; i < n; i++) {  b[i].x = node[i].x;  b[i].y = node[i].y; } //划分为两个子问题,递归求解子问题 double d1 = closestPoints(node, m + 1);  //得到S1中的最近距离d1 double d2 = closestPoints(b, n - m - 1); //得到S2中的最近距离d2 double dm = min(d1, d2);     //求得d1与d2两者之间较小值      int f,p;  //记录点的个数 p = 0for(i = 0; i <= m; i++)    //找出S1中与x=m的距离小于dm的所有点,保存在结构体c当中 {  if(dx(node[i].x,node[m].x) < dm)  {   c[p].x = node[i].x;   c[p].y = node[i].y;   p++;  } } f=0for(i = m + 1; i < n; i++)   //找出S2中与x=m的距离小于dm的所有点,保存在结构题d当中 {  if(dx(node[i].x, node[m].x) < dm)  {   d[f].x = node[i].x;   d[f].y = node[i].y;   f++;  } } sort(c, c+p,cmp); //按照y轴的坐标值升序排列 sort(d, d+f,cmp); double ret = Dist; for(i = 0; i < p; i++)  //遍历比较分别在S1和S2中两点之间的距离 {  for(j = 0; j < f; j++)  {   double ans = ds(c[i], d[j]);   ret = min(ret, ans);  //得出最近对距离  } } return min(ret, dm);  //返回第三种情形与前两种情形较小值}int main(void) {   int n,i;   for(int w=0;w<6;w++)   {     cout<<"输入坐标的数目:"<<endl;     cin>>n;     srand((unsigned)time(NULL));     for(i=0;idouble)(RAND_MAX/10000);       node[i].y=rand()/(double)(RAND_MAX/10000);     }     sort(node,node+n,cmp);     clock_t start,end;     start=clock();  closestPoints(node,n);               //系统调用十次分治法函数。     closestPoints(node,n);     closestPoints(node,n);     closestPoints(node,n);     closestPoints(node,n);     closestPoints(node,n);     closestPoints(node,n);     closestPoints(node,n);     closestPoints(node,n);     closestPoints(node,n);     end=clock();     cout<<"分治法求最近对用时为"<<double(end-start)/CLOCKS_PER_SEC<<"ms"<<endl;     cout<<"==========================================================="<<endl;   } system("pause"); return 0;} 





           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

你可能感兴趣的:(算法设计--蛮力法 分治法求最近对问题(C++实现))