1. 程式人生 > >POJ 2069最小球覆蓋 HDU3007最小圓覆蓋【模擬淬火演算法】

POJ 2069最小球覆蓋 HDU3007最小圓覆蓋【模擬淬火演算法】

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;
}