萌新求助模拟退火
查看原帖
萌新求助模拟退火
369041
bdfs_then_csdn楼主2023/3/18 09:57

写了个模拟退火,自认为挺对,但是WA40,感觉是随机的时候正确性有点问题,但是不知道哪里不对……

#include<bits/stdc++.h>
using namespace std;
const double down=0.997;
int n,m,r;double lx,ly,nx,ny,x[1000001],y[1000001],len[1000001],xx[1000001],yy[1000001],mx,my,sx,sy;
int sqr(double ax,double ay){
	double lenn=r;int ans=0;
	for(int i=1;i<=n;i++)lenn=min(lenn,sqrt((ax-x[i])*(ax-x[i])+(ay-y[i])*(ay-y[i]))-len[i]);
	for(int i=1;i<=m;i++)if(sqrt((ax-xx[i])*(ax-xx[i])+(ay-yy[i])*(ay-yy[i]))<=lenn)ans++;
	return ans;
}
void sa(){
	double t=10000;
	while(t>1e-9){
		double nx=lx+(rand()*2-RAND_MAX)*t,ny=ly+(rand()*2-RAND_MAX)*t;
		while(fabs(nx)>mx)nx/=2;
		while(fabs(ny)>my)ny/=2;
		double dt=sqr(lx,ly)-sqr(nx,ny);
		if(dt<0)lx=nx,ly=ny;
		else if(exp(-dt/t)*RAND_MAX>rand())lx=nx,ly=ny;
		t*=down;
	}
}
int main(){
	srand(time(0));
    lx=ly=0;cin>>n>>m>>r;
    for(int i=1;i<=n;i++)scanf("%lf%lf%lf",&x[i],&y[i],&len[i]);
    for(int i=1;i<=m;i++)scanf("%lf%lf",&xx[i],&yy[i]),mx=max(mx,fabs(xx[i])),my=max(my,fabs(yy[i])),sx+=xx[i],sy+=yy[i];
    lx=sx/m,ly=sy/m;for(int i=1;i<=10;i++)sa();
    printf("%d\n",sqr(lx,ly));
    return 0;
}
2023/3/18 09:57
加载中...