分治法解决最小套圈问题
来源:互联网 发布:淘宝新品促销海报图 编辑:程序博客网 时间:2024/04/28 20:09
/* Copyright by ZhongMing-Bian Jan,6,2010 */
/* 分治法解决最小套圈问题 */
/* Jan,11 debug ;input question */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_POINTS 100000 /*坐标点数的最大值 */
#define MAX_TEST 100 /*最大测试次数*/
typedef struct { /*定义坐标点*/
float x;
float y;
}Point;
float dist(Point a, Point b) { /*求两个坐标点之间的距离*/
return sqrt((float)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
float Nearest(Point* points, int n){ /*求最小距离*/
float temp1,temp2,temp3,temp,nearest;
float left,right,d; /*当n小于4时,T(n)=O(1);*/
int i,j;
if(n==1) return 999999999; /*一个点情形,返回值模拟无穷*/
if(n==2) return dist(points[0], points[1]); /*两个点情形*/
if(n==3){ /*三个点情形*/
temp1=dist(points[0], points[1]);
temp2=dist(points[0], points[2]);
temp3=dist(points[1], points[2]);
return temp3<((temp1<temp2)?temp1:temp2)?temp3:((temp1<temp2)?temp1:temp2);
}
/*多于3点的情形,用分治法*/
left=Nearest(points,n/2); /*递归求解*/
right=Nearest(&points[n/2],n-n/2);
d=left<right?left:right;
/*综合中间带求得最小距离*/
nearest=d;
for(i=0;i<n/2;i++)
/* 通过扫描子集一中每个点检查子集二中与其距离在d之内的
所有点(最多6个)以完成合并*/
for(j=n/2;j<n&&(fabs(points[j].y-points[i].y)<d);j++){
temp=dist(points[i],points[j]);
nearest=nearest<temp?nearest:temp;
}
return nearest;
}
int compx(const void* a, const void* b) {
/*实现按x排序*/
return ((Point*)a)->x-((Point*)b)->x;
}
int compy(const void* a, const void* b) {
/*实现按y排序*/
return ((Point*)a)->y-((Point*)b)->y;
}
void main() {
int i,j=0,numPoints;
Point points[MAX_POINTS];
float result[MAX_TEST]; /*记录结果*/
for(i=0;i<MAX_TEST;i++) result[i]=-1;
printf("请输入数据:/n");
while(1){ /*进行多次测试*/
loop: scanf("%d", &numPoints);
if(!numPoints) break;
if(numPoints<0||numPoints>MAX_POINTS) {
printf("Error!/n"); /*容错处理*/
goto loop;
}
for(i=0; i<numPoints; i++) /*输入点的数量及点的坐标值*/
scanf("%f %f", &points[i].x, &points[i].y);
/*预排序,在使用分治法之前,预先将S中的n个点依其y坐标排序好。*/
qsort(points, numPoints, sizeof(Point), compx);
qsort(points, numPoints/2, sizeof(Point), compy);
qsort(points+numPoints/2, numPoints-numPoints/2, sizeof(Point), compy);
result[j]=Nearest(points, numPoints)/2;
j++;
}
i=0;
printf("/n最短距离分别为:/n");
while(result[i]!=-1) /*输出测试结果*/
printf("%.2f/n",result[i++]);
}
- 分治法解决最小套圈问题
- 分治法:最小套圈问题【分析】
- 最小套圈问题双重循环算法
- 最小圈基问题
- 分治法解决日程安排问题
- 分治法解最大最小问题
- 三圈问题的解决
- 使用分治法解决棋盘覆盖问题
- 分治法解决大整数乘法问题
- 分治法解决最大子数组问题
- 利用分治法解决棋盘覆盖问题
- 分治法解决快速排序问题
- 利用分治法解决凸包问题
- 分治法解决凸包问题
- 最小圈
- 基于分治法的求最大最小问题
- 分治解决假硬币问题
- o.boj 1475 套圈
- 找到100到1000之间的素数
- Linux 多线程应用中编写安全的信号处理函数
- 获取操作系统语言
- 分治法:最小套圈问题【分析】
- 最小套圈问题双重循环算法
- 分治法解决最小套圈问题
- 只需你十分钟却可以让你和你的父母都至少多活十年
- 大量Ophone/Android技术文章推荐
- 【转】xp修复win7启动项方法
- BREW应用自动安装
- 支持BREW的手机
- BREW 在手机中的软件层次
- 永远相信明天会更好
- BREW与手机操作系统的关系