平面最接近点对问题(分治法)
平面最接近点对问题(分治法)
问题描述参见:https://www.cnblogs.com/zyxStar/p/4591897.html
代码参考:http://blog.csdn.net/qq_28666193/article/details/53351482(原代码中有几处错误,我作了修改)
头文件部分:
(1)数据结构部分:
//涉及的数据结构
#ifndef DATASET_H
#define DATASET_H
struct point{ //点结构
double x, y;
};
#endif
(2)函数声明部分:
//函数头文件 //======================================= #ifndef FUNC_H #define FUNC_H #include "dataset.h" double closest_distance(point s[], int low, int high, point rec[]); double Distance(point a, point b); bool comp_x(point a, point b); bool comp_y(point a, point b); #endif
源文件部分:
(1)函数实现部分:
//求解最近距离的函数实现
#include "dataset.h"
#include <math.h>
#include <algorithm>
using namespace std;
double Distance(point a, point b) //计算两点距离
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) - (a.y - b.y));
}
bool comp_x(point a, point b) //按x升序判别函数
{
return a.x < b.x;
}
bool comp_y(point a, point b) //按y升序判别函数
{
return a.y < b.y;
}
//函数实现:rec[]存储最接近点对;
double closest_distance(point s[], int low, int high, point rec[])
{
double d1, d2, d3, d;
int mid, i, j, index;
double x1, y1, x2, y2; //记录最近的点对
point *P = new point[high - low + 1];
point temp_1[2], temp_2[2], temp_3[2];
if (high - low == 1) //两个点时的情况
{
rec[0].x = s[low].x; rec[0].y = s[low].y;
rec[1].x = s[high].x; rec[1].y = s[high].y;
return Distance(s[low], s[high]);
}
if (high - low == 2) //三个点时的情况
{
d1 = Distance(s[low], s[low + 1]);
d2 = Distance(s[low + 1], s[high]);
d3 = Distance(s[low], s[high]);
if ((d1 <= d2) && (d1 <= d3)) //这里在判断三种情况时,第二种情况没必要使用(d2<d3)&&(d2<d1),相较更繁琐了;
{
rec[0].x = s[low].x; rec[0].y = s[low].y;
rec[1].x = s[low + 1].x; rec[1].y = s[low + 1].y;
return d1;
}
else if (d2 < d3)
{
rec[0].x = s[low + 1].x; rec[0].y = s[low + 1].y;
rec[1].x = s[high].x; rec[1].y = s[high].y;
return d2;
}
else
{
rec[0].x = s[low].x; rec[0].y = s[low].y;
rec[1].x = s[high].x; rec[1].y = s[high].y;
return d3;
}
}
mid = (low + high) / 2;
d1 = closest_distance(s, low, mid, rec);
temp_1[0] = rec[0];
temp_1[1] = rec[1];
d2 = closest_distance(s, mid + 1 ,high, rec);
temp_2[0] = rec[0];
temp_2[1] = rec[1];
if (d1 <= d2)
{
d = d1;
rec[0] = temp_1[0];
rec[1] = temp_1[1];
}
else
{
d = d2;
rec[0] = temp_2[0];
rec[1] = temp_2[1];
}
index = 0;
for (i = mid; (i >= low) && ((s[mid].x - s[i].x) < d); i--)
{
P[index++] = s[i]; //点集合P1
}
for (i = mid + 1; (i <= high) && ((s[i].x - s[mid].x) < d); i++)
{
P[index++] = s[i]; //点集合P2
}
sort(P, P + index, comp_y); //升序排列
for (i = 0; i < index; i++)
{
for (j = i + 1; j < index; j++)
{
if ((P[j].y - P[i].y) >= d)
break;
else
{
d3 = Distance(P[i], P[j]);
if (d3 < d)
{
rec[0].x = P[i].x; rec[0].y = P[i].y;
rec[1].x = P[j].x; rec[1].y = P[j].y;
d = d3;
}
}
}
}
delete []P; //注意动态内存的删除方式,防止内存泄漏
return d;
}
(2)主函数部分:
//2018_02_24
//使用分治法求解二维平面最接近点问题
//=============================================================
#include <iostream>
#include <math.h>
#include <algorithm>
#include "dataset.h" //数据结构实现放在这个头文件中
#include "func.h" //函数声明的头文件
using namespace std;
int main(void)
{
point p[10]; //设定点的集合
int n;
double minDist;
cout << "输入点的个数:\n";
cin >> n;
cout << "输入点集:(x , y) \n";
for (int i = 0; i < n; i++)
cin >> p[i].x >> p[i].y;
sort(p, p + n, comp_x); //对输入的点先进行排序
point index[2];
minDist = closest_distance(p, 0, n - 1, index);
cout << "最小距离点对为:(" << index[0].x << "," << index[0].y << "),(" << index[1].x << "," << index[1].y << ")";
cout << "最小距离为:\n" << minDist;
system("pause");
return 0;
}
最后,结果如下:



浙公网安备 33010602011771号