最小球覆盖问题

2024-08-14

采用模拟退火算法,求解计算几何中的最小球覆盖问题

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