您的位置:首页 > 其它

寻找最近点对

2012-12-06 22:41 148 查看
fcpp.h

#ifndef FCCP_H
#define FCCP_H

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>

typedef int ElemType;

ElemType position(ElemType a[],ElemType b[],int start,int end);

void swap(ElemType &a,ElemType &b)
{
ElemType temp;
temp = a;
a = b;
b = temp;
}

void sortTwo(ElemType a[],ElemType b[],int start,int end)//使用快速排序实现对a的排序,其中保持b中元素位置相对于a不变
{
if(start < end)
{
int pos = position(a,b,start,end);
sortTwo(a,b,start,pos-1);
sortTwo(a,b,pos+1,end);
}
}

ElemType position(ElemType a[],ElemType b[],int start,int end)//快速排序求划分位置方法
{
ElemType temp = a[start],temp2 = b[start];
int i = start,j = end;

while(i < j)
{
while(j > i && a[j] >= temp)
{
j--;
}
if(i < j)
{
a[i] = a[j];
b[i] = b[j];
}
while(j > i && a[i] <= temp)
{
i++;
}
if(i < j)
{
a[j] = a[i];
b[j] = b[i];
}
}
a[i] = temp;
b[i] = temp2;
return i;
}

void sort(ElemType a[],ElemType b[],int n)//对按照a排序后中a值相同的情况再按照b中元素的大小进行排序
{
for(int i = 0;i < n-1;)
{
int s,e;
while(a[i] != a[i+1] && i < n-1)
{
i++;
}
s = i;
while(a[i] == a[i+1] && i < n-1)
{
i++;
}
e = i;
for(int j = s;j <= e;j++)
{
for(int m = e-s+j;m > j;m--)
{
if(b[m] < b[m-1])
{
swap(b[m],b[m-1]);
}
}
}
i++;
}
}

//---fccp是求解n个点中距离最小的2个点的距离和点的坐标
void fccp(int start,int end,ElemType x[],ElemType y[],ElemType idn[],double &minLen,ElemType &px,ElemType &py,ElemType &qx,ElemType &qy)
{
int m = end-start+1;//每一步都要判断准确,是大的减去小的才行
qx = qy = px = py = 0;
if(m <= 3)//m<=3的情况
{
minLen = 10000;
for(int i = 0;i < m-1;i++)
{
for(int j = i+1;j <= m-1;j++)
{
int ylen = y[j]-y[i];
int xlen = x[idn[j]] - x[idn[i]];
xlen = xlen > 0 ? xlen : -xlen;
double mlen = sqrt((double)(ylen*ylen+xlen*xlen));
if(minLen > mlen)
{
minLen = mlen;
px = x[idn[i]];
py = y[i];
qx = x[idn[j]];
qy = y[j];
}
}
}
}
else//m>=4的情况
{
ElemType *YL,*IDNL,*YR,*IDNR;

int r = m/2;//右边数组长度
int l = m-r;//左边数组长度
int lengthL = 0;
int lengthR = 0;

YL = (ElemType *)malloc(sizeof(ElemType)*l);
IDNL = (ElemType *)malloc(sizeof(ElemType)*l);
YR = (ElemType *)malloc(sizeof(ElemType)*r);
IDNR = (ElemType *)malloc(sizeof(ElemType)*r);

for(int i = 0;i < m;i++)
{
if(idn[i] <= start+l-1)
{
YL[lengthL] = y[i];
IDNL[lengthL] = idn[i];
lengthL++;
}
else
{
YR[lengthR] = y[i];
IDNR[lengthR] = idn[i];
lengthR++;
}
}

double mlenl,mlenr;
ElemType qxl,qxr,qyl,qyr,pxl,pxr,pyl,pyr;

fccp(start,start+l-1,x,YL,IDNL,mlenl,pxl,pyl,qxl,qyl);
fccp(start+l,end,x,YR,IDNR,mlenr,pxr,pyr,qxr,qyr);

if(mlenl < mlenr)
{
minLen = mlenl;
px = pxl;
py = pyl;
qx = qxl;
qy = qyl;
}
else
{
minLen = mlenr;
px = pxr;
py = pyr;
qx = qxr;
qy = qyr;
}

double xdiv = (double)(x[start+l-1]+x[start+l])/2;//求分割线

ElemType *YC,*IDNC;
YC = (ElemType *)malloc(sizeof(ElemType)*m);
IDNC = (ElemType *)malloc(sizeof(ElemType)*m);
int lengthC = 0;

for(int i = 0;i < m;i++)
{
if(x[idn[i]] > xdiv-minLen && x[idn[i]] < xdiv+minLen)
{
YC[lengthC] = y[i];
IDNC[lengthC] = idn[i];
lengthC++;
}
}

if(lengthC <= 0)
{
return;
}

for(int i = 0;i < lengthC-1;i++)
{
ElemType ypres = y[i];
ElemType xpres = x[IDNC[i]];
int u = (i+4) > lengthC-1 ? lengthC-1 : (i+4);//u是检查的最大下标
int v = i+1;
while(v <= u && YC[v]-ypres < minLen)
{
ElemType tempYlen = YC[v]-ypres;
ElemType tempXlen = x[IDNC[v]] - xpres;
tempXlen = tempXlen>0 ? tempXlen : -tempXlen;
double tempLen = sqrt((double)(tempXlen*tempXlen+tempYlen*tempYlen));
if(tempLen < minLen)
{
minLen = tempLen;
px = xpres;
py = ypres;
qx = x[IDNC[v]];
qy = YC[v];
}
v++;
}
}
}
}

#endif


main.cpp

#include "fcpp.h"

int main()
{
//这里先测试数据可以重复,x相同的情况下按照y从小到大排列
int x[8] = {1,9,3,4,6,7,2,8};
int y[8] = {5,6,8,12,1,7,4,9};
int idn[8] = {0,1,2,3,4,5,6,7};

sortTwo(x,y,0,7);
sort(x,y,8);

/*
for(int i = 0;i < 8;i++)
{
printf("%d ",x[i]);
}
printf("\n");
for(int i = 0;i < 8;i++)
{
printf("%d ",y[i]);
}
printf("\n");
for(int i = 0;i < 8;i++)
{
printf("%d ",idn[i]);
}
printf("\n");
*/

sortTwo(y,idn,0,7);

/*
for(int i = 0;i < 8;i++)
{
printf("%d ",x[i]);
}
printf("\n");
for(int i = 0;i < 8;i++)
{
printf("%d ",y[i]);
}
printf("\n");
for(int i = 0;i < 8;i++)
{
printf("%d ",x[idn[i]]);
}
printf("\n");
*/

ElemType px,py,qx,qy;
double minLen;

fccp(0,7,x,y,idn,minLen,px,py,qx,qy);

printf("the shortest length between the two points is : %lf\n\n",minLen);
printf("the point is ( %d , %d ) and ( %d , %d )",px,py,qx,qy);

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: