当前位置:   article > 正文

最近对问题_最近对问题输入什么

最近对问题输入什么

问题:最近对问题

/*

第一种方法:蛮力法解决的最近对问题

*/

C++代码如下:

  1. #include<iostream>
  2. using namespace std;
  3. #define N 1005
  4. int x[N],y[N];
  5. int ClosestPoints(int x[],int y[],int n)
  6. {
  7. int index1,index2;//记录点对
  8. int d,minDist = 1000000;//假设最大距离不超过1000000
  9. for(int i=0;i<n-1;i++)
  10. for(int j=i+1;j<n;j++)
  11. {
  12. d=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
  13. if(d<minDist)
  14. {
  15. minDist = d;
  16. index1=i+1;
  17. index2=j+1;
  18. }
  19. }
  20. cout<<"最近对的点对是: "<<index1<<" and "<<index2<<endl;
  21. cout<<"最近对的距离是:";
  22. return minDist;
  23. }
  24. int main()
  25. {
  26. int n;
  27. cout<<"请输入点的对数: ";
  28. cin>>n;
  29. cout<<"请依次输入(x,y)的值: "<<endl;
  30. for(int i=0;i<n;i++)
  31. cin>>x[i]>>y[i];
  32. cout<<ClosestPoints(x,y,n);
  33. return 0;
  34. }

运行截图如下:

第二种方法:分治法解决

分析:用分治法解决最近对问题,很自然的想法就是将集合S分成两个子集 S_{1}和 S_{2},每个子集中有n/2个点。然后在每个子集中递归地求其最接近的点对,在求出每个子集的最接近点对后,在合并步中,如果集合 S 中最接近的两个点都在子集 S_{1}或 S_{2}中,则问题很容易解决,如果这两个点分别在 S_{1}和 S_{2}中,问题就比较复杂了。

伪代码:

https://img-blog.csdn.net/20181019173323848?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N4aF8xMjMx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70C++代码如下:

  1. #include <iostream>
  2. #include <math.h>
  3. using namespace std;
  4. const int n = 8;
  5. //定义结构体表示集合S中的 点的坐标
  6. struct point{
  7. int x, y;
  8. };
  9. double Closest(point S[], int low, int high); //实现求最近对距离
  10. double Distance(point a, point b); //求两点之间距离
  11. int Partition(point r[], int first, int end); //划分【课本P62】
  12. void QuickSort(point r[], int first, int end); //快速排序【课本P63】
  13. //实现求最近对距离
  14. double Closest(point S[], int low, int high){
  15. double d1, d2, d3, d;
  16. int mid, i, j, index;
  17. point P[n]; //存放点集合 P1和P2
  18. //如果只有两个点,返回这两个点间的距离
  19. if (high - low == 1) {
  20. return Distance(S[low], S[high]);
  21. }
  22. //如果有三个点,求最近点对距离
  23. if (high - low == 2) {
  24. d1 = Distance(S[low], S[low + 1]);
  25. d2 = Distance(S[low + 1], S[high]);
  26. d3 = Distance(S[low], S[high]);
  27. if ((d1 < d2) && (d1 < d3)) return d1;
  28. else if (d2 < d3) return d2;
  29. else return d3;
  30. }
  31. mid = (low + high) / 2; //计算中间点
  32. d1 = Closest(S, low, mid); //递归求解子问题①
  33. d2 = Closest(S, mid + 1, high); //递归求解子问题②
  34. if (d1 <= d2) d = d1; //已下为求解子问题③
  35. else d = d2;
  36. index = 0;
  37. for (i = mid; (i >= low) && (S[mid].x - S[i].x < d); i--) //建立点集合P1
  38. P[index++] = S[i];
  39. for (i = mid + 1; (i <= high) && (S[i].x - S[mid].x < d); i++) //建立点集合P2
  40. P[index++] = S[i];
  41. //对集合P1、P2按y坐标升序排列
  42. QuickSort(P, 0, index - 1);
  43. //依次处理集合P1和P2中的点
  44. for (i = 0; i < index; i++) {
  45. for (j = i + 1; j < index; j++) {
  46. if (P[j].y - P[i].y >= d) //超出y坐标的范围,点P[i]处理完毕
  47. break;
  48. else {
  49. d3 = Distance(P[i], P[j]);
  50. if (d3 < d)
  51. d = d3;
  52. }
  53. }
  54. }
  55. return d;
  56. }
  57. //求两点之间距离
  58. double Distance(point a, point b){
  59. return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
  60. }
  61. int Partition(point r[], int first, int end){ //划分
  62. int i = first, j = end; //初始化待划分区间
  63. while (i < j) {
  64. while (i < j && r[i].y <= r[j].y) j--; //右侧扫描
  65. if (i < j) {
  66. point temp = r[i]; r[i] = r[j]; r[j] = temp; //将较小记录交换到前面
  67. i++;
  68. }
  69. while (i < j && r[i].y <= r[j].y) i++; //左侧扫描
  70. if (i < j) {
  71. point temp = r[i]; r[i] = r[j]; r[j] = temp; //将较大记录交换到后面
  72. j--;
  73. }
  74. }
  75. return i; // 返回轴值记录的位置
  76. }
  77. void QuickSort(point r[], int first, int end){ //快速排序
  78. int pivot;
  79. if (first < end) {
  80. pivot = Partition(r, first, end); //划分,pivot是轴值在序列中的位置
  81. QuickSort(r, first, pivot - 1); //求解子问题1,对左侧子序列进行快速排序
  82. QuickSort(r, pivot + 1, end); //求解子问题2,对右侧子序列进行快速排序
  83. }
  84. }
  85. int main()
  86. {
  87. //输入按x坐标升序排列的n个点的集合
  88. point S[n] = { {1,4},{1,8},{2,1},{3,2},{4,4},{5,1},{6,6},{7,2} };
  89. double minDist = Closest(S, 0, n - 1);
  90. //输出最近点对的距离
  91. cout << "最近点对距离为:"<< minDist << endl;
  92. return 0;
  93. }

运行截图如下

时间复杂度T(n)=O(nlog2n)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/640414
推荐阅读
相关标签
  

闽ICP备14008679号