我想的是不停地调整方差,直到为零为止。 向一个方向走到头就换方向。
#include<bits/stdc++.h>
#define sr register short
#define su unsigned short
#define r register int
#define u unsigned int
#define ll long long
#define i64 ll
#define llr register ll
#define llu unsigned ll
#define lf double
#define Lf long lf
#define delta 0.999
using namespace std;
struct node
{
lf x[15];
}poi[15],ans,a;
int n,tim=0;
lf answ,t;
lf calculate(node m)
{
lf cul=0,ave=0,res=0;
for(r i=1;i<=n+1;i++)
{
node d;
for(r j=1;j<=n;j++)
{
d.x[j]=m.x[j]-poi[i].x[j];
cul+=d.x[j]*d.x[j];
}
ave+=sqrt(cul);
cul=0;
}
ave/=n+1;
for(r i=1;i<=n+1;i++)
{
node d;
for(r j=1;j<=n;j++)
{
d.x[j]=m.x[j]-poi[i].x[j];
cul+=d.x[j]*d.x[j];
}
res+=(sqrt(cul)-ave)*(sqrt(cul)-ave);
}
return res;
}
void SA()
{
node m;
int dri=1;
for(r i=1;i<=n;i++)
m.x[i]=ans.x[i];
t=3000;
while(t>1e-15)
{
node d;
for(r i=1;i<=n;i++)
d.x[i]=m.x[i]+dri*((rand()<<1)-RAND_MAX)*t;
lf now=calculate(d);
lf Delta=answ-now;
if(Delta<0)
{
for(r i=1;i<=n;i++)
{
ans.x[i]=d.x[i];
m.x[i]=d.x[i];
}
answ=now;
}
else
{
if(exp(-Delta/t)*RAND_MAX>rand())
for(r i=1;i<=n;i++)
m.x[i]=d.x[i];
dri*=-1;
}
t*=delta;
}
}
int main()
{
srand(time(0));
scanf("%d",&n);
answ=1e8;
for(r i=1;i<=n+1;i++)
for(r j=1;j<=n;i++)
{
scanf("%lf",&poi[i].x[j]);
a.x[j]+=poi[i].x[j];
}
for(r i=1;i<=n;i++)
ans.x[i]=a.x[i]/n+1;
for(r i=1;i<=tim;i++)
SA();
for(r i=1;i<=n;i++)
printf("%.3lf",ans.x[i]);
return 0;
}