采用模拟退火算法,求解计算几何中的最小球覆盖问题
#include <bits/stdc++.h>
#define io cin.tie(0), cout.tie(0), ios::sync_with_stdio(false)
#define LL long long
#define ULL unsigned long long
#define EPS 1e-8
#define INF 0x7fffffff
#define SUB -INF - 1
using namespace std;
struct Point
{
double x, y, z;
} p[35];
int n;
double Distance(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 T = 100.0;
double delta = 0.98;
Point c = p[0];
int pos;
double r;
while (T > EPS)
{
pos = 0;
r = 0;
for (int i = 0; i < n; i++)
if (Distance(c, p[i]) > r)
{
r = Distance(c, p[i]);
pos = i;
}
c.x += (p[pos].x - c.x) / r * T;
c.y += (p[pos].y - c.y) / r * T;
c.z += (p[pos].z - c.z) / r * T;
T *= delta;
}
return r;
}
int main()
{
double ans;
while (~scanf("%d", &n))
{
for (int i = 0; i < n; i++)
scanf("%lf%lf%lf", &p[i].x, &p[i].y, &p[i].z);
ans = solve();
printf("%.5lf\n", ans);
}
return 0;
}