找最近点对问题-分治算法的应用

本文探讨了如何运用分治策略来解决计算机科学中的经典问题——寻找二维空间中最近点对。通过将大问题分解为小问题并递归求解,算法有效地减少了计算复杂度,提高了效率,对于大规模数据集尤为适用。
摘要由CSDN通过智能技术生成

 

    分治算法的基本思想是:
    分(divide):递归求解子问题,即:分解+求解,将问题分解为k个方便求解的小问题。
    为什么说是递归求解呢,这里可以看作将一个问题分2个子问题,如果2个子问题还是大,再继续分成4个子问题,直到分解到能方便求解的小问题。也就是说分治算法是含有2个以上的递归运算,只有一个递归的例程不能算做分治算法。
    治(conquer):从子问题构建原问题的解。
    对于分治,最长用到的复杂度分析情况为:
    T(N) = aT(N/b) + O(N^k)
    当a=b^k时, T(N)=O(N^k*logN)
    比如,非常常见的二分法: T(N) = 2T(N/2) + O(N) ,此时a=2, b=2, k=1 即a=b^k,所以 该算法的复杂度为 O(NlogN)
     从另一个角度,反向分析问题,如果我们希望得到一个O(NlogN)的算法,那么就需要保证附加工作为O(N),这是一个非常非常关键的利用分治算法解决问题的入手点!!!
    而且这个复杂度也是大多数分治算法问题的情况。 当然还有另外两种>, < 情况,就参考书上的详细讲解吧。
    
    下面以一个例子详细介绍如何应用分治算法。
    最近点对问题:给定平面上的N个点,找出距离最近的两个点。
    对于该问题,算法过程并不算复杂,但要想编程实现,需要克服不少细节问题。
    首先应该实现Point类:
     Point.h:
#include <iostream>
class Point
{
public :
    Point( double x , double y);
    double getx() const
    {
        return m_x;
    }
    double gety() const
    {
        return m_y;
    }
    friend std :: ostream & operator <<( std :: ostream & os , const Point & p);
   
private :
    double m_x;
    double m_y;
};
    Point.cpp:
#include "Point.h"

Point :: Point( double x , double y) : m_x( x ), m_y( y)
{
}

std :: ostream & operator <<( std :: ostream & os , const Point & p)
{
    os << "P(" <<p . getx() << "," <<p . gety() << ")";
    return os;
}
 
    这里有几点要注意:重载<<,友元函数的应用,初始化的位置。不多介绍了,代码很简单,上点心看看就好。 
    接下来,是解决该问题的具体过程:
    1. 最简单的解法就是蛮力法:把每两个点的距离求出来,然后找出最小值即可。
       虽然,该算法很简单,但编程实现时,从该笨方法起步会有一个很好的过渡,不至于编码难度过陡。
       于是我们需要:计算两点距离的函数 Distance, 求最近点对函数 FindShortPair, 一组点 Point p []用以测试, 打印点函数 PrintPoints用于观察。
       代码如下:       上面的代码完成了很多该问题算法的外围工作,最重要的是提供了测试环境。注意const的应用,double,int型的定义。
#include "Point.h"
#include <cmath>

double Distance( const Point & s , const Point & t)
{
    double squarex = ( s . getx() - t . getx() ) * ( s . getx() - t . getx() );
    double squarey = ( s . gety() - t . gety() ) * ( s . gety() - t . gety() );
    return sqrt( squarex + squarey );
}

void FindShortPair( const Point * p , int num)
{ //can only find one of the shortest path
    double distance = Distance(p [ 0 ], p [ 1 ]);
    int start = 0;
    int end = 1;
    for ( int i = 0; i < num; i ++)
    {
        for (
  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值