mxqz模拟退火调参
查看原帖
mxqz模拟退火调参
234074
樱雪喵>w<楼主2022/11/22 11:15

RT,不知道是参数问题还是算法正确性问题,用小号交了两页最高只有 60pts,球大佬帮忙康康是不是犯了什么奇怪错误或者帮着调调参/kel/kel

思路参照第一篇题解。

#include<bits/stdc++.h>
using namespace std;
typedef double db;
const db eps=1e-7;
const int N=1005;
int n,m;
db x,y,r;
db Rand() {return (db)rand()/RAND_MAX;} 
struct node{
	db x,y,r;
}b[N];
struct Node{
	db x,y;
}d[N];
int cnt,ans;
db dis(db a,db b,db c,db d){
	return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
db check(db x,db y)
{
	cnt=0;db R=r,mn=2e9;
	for(int i=1;i<=n;i++) 
		R=min(R,dis(x,y,b[i].x,b[i].y)-b[i].r);
	for(int i=1;i<=m;i++)
	{
		db di=dis(x,y,d[i].x,d[i].y);
		if(di<=R+eps) cnt++;
		mn=min(mn,di-R);
	}
	return -15.0*mn+cnt;
}
void SA()
{
	db T=100000,down=0.998;
	x=y=0;
	while(T>eps)
	{
		db nx=x+(Rand()*2.0-1)*T;
		db ny=y+(Rand()*2.0-1)*T;
		db del=check(nx,ny)-check(x,y);
		ans=max(ans,cnt);
		if(del>0) x=nx,y=ny;
		else if(exp(del/T)>Rand()) x=nx,y=ny;
		T*=down;
	}
	for(int i=1;i<=1000;i++)
	{
		db nx=x+(Rand()*2.0-1)*50;
		db ny=y+(Rand()*2.0-1)*50;
		check(nx,ny);
		if(cnt>ans) ans=cnt,x=nx,y=ny;
	}
}
int main()
{
	srand(47);
	clock_t st,ed;
	st=clock();
	scanf("%d%d%lf",&n,&m,&r);
	for(int i=1;i<=n;i++)
		scanf("%lf%lf%lf",&b[i].x,&b[i].y,&b[i].r);
	for(int i=1;i<=m;i++)
		scanf("%lf%lf",&d[i].x,&d[i].y);
	SA();
	srand(114514);
	SA();
	printf("%d\n",ans);
	return 0;
}
/*
一些种子和他们对应通过的点(?
47     1 2   7 8
74     1     7 8
114514 1   5 7 8 9
512107 1     7 8 9
123    1     7 8 9
321    1     7 8
191981 1   5 7
1919810 1    7 8 9
*/
2022/11/22 11:15
加载中...