经典算法:最短点对
  Gjs2egXd7m0h 2023年11月02日 89 0


                                                                          软件架构师何志丹

说明

旧文新发,改了错别字,死链等。尽量保持“原汁原味”。

难点

如何测试。我的解决方式是:a,三种解法,看结果是否一致。b,小数据(100个点),人工排查。第一种方法,暴力法适合小数据。第二种方法:我的改进型。第三种方法:经典方法(分治法)。实验证明1000万数据时,我的算法有优势。

改进

暴力算法,O(n2)。我的改进型要点:先对所有数据按Y排序。只比较y距离小于等于已知最小距离的点对。经典方法:按Y排序,分成两部分,递归调用。合并时只比较距离分界线不超过已知最小距离的点对。
实际证明500万数据以下,我的改进算法明显优于经典算法;1000万数据时,略强于经典算法。

经典算法:最短点对_算法

核心源码节选:

double Dis(const CPT& pt1,const CPT& pt2)
{
	return sqrt((double) (pt1.x-pt2.x)*(pt1.x-pt2.x)+(pt1.y-pt2.y)*(pt1.y-pt2.y)+(pt1.z-pt2.z)*(pt1.z-pt2.z) );
}

void InitData(CPT* pts,int iNum)
{
	srand(time(NULL));

	for( int i = 0 ; i < iNum ; i++)
	{
		pts[i].x = rand()%10000;
		pts[i].y = rand()%10000;
		pts[i].z = rand()%10000;
	}
}

double Fun1(CPT* pts,const int iNum)
{
	 double dMinDis = 10000*10000 ;
	for(int i = 0 ; i < iNum ; i++ )
		for( int j = i+1 ; j < iNum ; j++ )
		{
			const double d = Dis(pts[i] , pts[j]);
			if( d < dMinDis)
			{
				dMinDis = d ;
			}
		}
		return dMinDis;
}

class CCmpY
{
public:
	bool operator()(const CPT& pt1,const CPT& pt2)
	{
		return pt1.y < pt2.y ;
	}
};

double Fun2(CPT* pts,const int iNum)
{
	std::sort(pts,pts+iNum,CCmpY() );

	double dMinDis = 10000*10000 ;
	for(int i = 0 ; i < iNum ; i++ )
		for( int j = i+1 ; j < iNum ; j++ )
		{
			const double d = Dis(pts[i] , pts[j]);
			if( d < dMinDis)
			{
				dMinDis = d ;
			}
			if( abs(pts[i].y - pts[j].y )> dMinDis )
			{
				break;
			}
		}
		return dMinDis;
}

double Fun3(CPT* pts,const int iNum)
{
	std::sort(pts,pts+iNum,CCmpY() );

	if( iNum < 100 )
	{
		return Fun1(pts,iNum);
	}

	const int iMid = iNum/2 ;
	const double dMin1 = Fun3(pts,iMid);
	const double dMin2 = Fun3(pts+iMid,iNum-iMid);
	double dMinDis = min(dMin1,dMin2) ;
	for(int i = iMid-1 ; i >= 0 ; i-- )//左集合
	{
		if( abs(pts[i].y - pts[iMid].y ) > dMinDis )
		{
			break;
		}
		for( int j = iMid ; j < iNum ; j++ )//右集合
		{
			const double d = Dis(pts[i] , pts[j]);
			if( d < dMinDis)
			{
				dMinDis = d ;
			}
			if( abs(pts[i].y - pts[j].y )> dMinDis )
			{
				break;
			}
		}
	}
		return dMinDis;
}

测试环境

似乎是WinXP VS2005(VC8)

下载

可通过以下链接下载测试数据,exe,源码(VS2005,VC8)

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  8Tw5Riv1mGFK   2024年05月01日   80   0   0 C++
  BYaHC1OPAeY4   2024年05月08日   58   0   0 C++
  yZdUbUDB8h5t   2024年04月29日   59   0   0 C++
  yZdUbUDB8h5t   2024年05月05日   44   0   0 C++
  oXKBKZoQY2lx   2024年05月17日   58   0   0 C++
Gjs2egXd7m0h