蒟蒻求助ing
查看原帖
蒟蒻求助ing
192534
棒小糖楼主2020/7/7 18:33

我想的是不停地调整方差,直到为零为止。 向一个方向走到头就换方向。

#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;
}
2020/7/7 18:33
加载中...