平面最接近點對問題(分治法)


問題描述參見: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;
}

 

最后,結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM