POJ 2069最小球覆盖
1.给定N个三维点,要求覆盖这些点的最小球半径; 2.采用模拟淬火算法,随机选取一个点作为初始解,然后不断向当前最远的点靠近; 3.这是一个不断调整的过程,对应模拟淬火算法中不断向内能最低这一目标函数(半径最小)逼近,温度对应控制变量- 对于一个点,球心就是这个点,且半径无穷小
- 对于两个点,球心就是两点线段的中点,半径就是线段长度的一半
- 对于三个点,三点构成的平面必为球的大圆,球心是三角形的外心,半径就是球心到某个点的距离
- 对于四个点,若四点共面,则转换到3点共面;若四点不共面,四面体可以唯一确定一个外接球
- 对于五个点及五个点以上,最小球必为某四个点的外接球
#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<climits>
#include<cstdlib>
using namespace std;
const double eps=1e-3;
//POJ2069 最小球覆盖
struct POINT{
double x,y,z;
}p[110];//N个点
POINT op;//最小球的球心
int n;
inline double dist(POINT &a,POINT &b){//两点距离
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}
double solve(){
double ret,delta=100.0;//温度
double maxDis,tempDis;
int i,id;
while(delta>eps){
id=0;
maxDis=dist(op,p[id]);
for(i=1;i<n;i++){
tempDis=dist(op,p[i]);
if(tempDis>maxDis){
maxDis=tempDis;
id=i;
}
}
ret=maxDis;
op.x+=(p[id].x-op.x)/maxDis*delta;
op.y+=(p[id].y-op.y)/maxDis*delta;
op.z+=(p[id].z-op.z)/maxDis*delta;
delta*=0.98;
}
return ret;//最小球半径
}
int main(){
while(scanf("%d",&n)!=EOF&&n){
for(int i=0;i<n;i++){
scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
}
printf("%lf\n", solve());
}
return 0;
}
HDU3007最小圆覆盖
给定N个二维点,求覆盖这些点的最小圆半径
#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<climits>
#include<cstdlib>
using namespace std;
const double eps=1e-8;
//HDU3001 最小圆覆盖
struct POINT{
double x,y,z;
}p[510];
POINT op;//最小圆的圆心
int n;
inline double dist(POINT &a,POINT &b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void solve(){
double ret,delta=100.0;
double maxDis,tempDis;
int i,id;
while(delta>eps){
id=0;
maxDis=dist(op,p[id]);
for(i=1;i<n;i++){
tempDis=dist(op,p[i]);
if(tempDis>maxDis){
maxDis=tempDis;
id=i;
}
}
ret=maxDis;
op.x+=(p[id].x-op.x)/maxDis*delta;
op.y+=(p[id].y-op.y)/maxDis*delta;
delta*=0.98;
}
printf("%.2lf %.2lf %.2lf\n",op.x,op.y,ret);
}
int main(){
while(scanf("%d",&n)!=EOF){
if(n==0) break;
op.x=op.y=0;
for(int i=0;i<n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
op.x+=p[i].x;
op.y+=p[i].y;
}
op.x/=n;
op.y/=n;
solve();
}
return 0;
}